Os componentes do Material Design (MDC, na sigla em inglês) ajudam os desenvolvedores a implementar o Material Design. Criados por uma equipe de engenheiros e designers de UX do Google, os MDC oferecem dezenas de componentes de IU bonitos e funcionais disponíveis para Android, iOS, Web e Flutter. material.io/develop |
No codelab MDC-103, você personalizou a cor, a elevação e a tipografia dos componentes do Material Design (MDC) para criar o estilo do app.
Um componente do sistema do Material Design realiza um conjunto de tarefas predefinidas e tem características específicas, como um botão. No entanto, um botão é mais do que apenas uma maneira de um usuário realizar uma ação. Ele também é uma expressão visual de forma, tamanho e cor que indica aos usuários que ele é interativo e que acontecerá algo quando os usuários clicarem ou tocarem nele.
As diretrizes do Material Design descrevem os componentes do ponto de vista de um designer. Elas descrevem uma grande variedade de funções básicas disponíveis nas plataformas, além dos elementos anatômicos que fazem parte de cada componente. Por exemplo, um pano de fundo contém uma camada de fundo e o conteúdo dela, uma camada em primeiro plano e o conteúdo dela, regras de movimento e opções de exibição. Cada um desses componentes pode ser personalizado conforme as necessidades, os casos de uso e o conteúdo de cada app. Essas partes são, na maioria, visualizações, controles e funções tradicionais do SDK da plataforma.
Embora as diretrizes do Material Design mencionem muitos componentes, nem todos são bons candidatos para serem reutilizados no código e, portanto, não podem ser encontrados nos MDC. Você pode criar essas experiências por conta própria para dar um estilo personalizado ao app. Tudo isso usando um código tradicional.
O que você vai criar
Neste codelab, você adicionará um pano de fundo a Shrine. Ele filtrará os produtos exibidos na grade assimétrica por categoria. Você usará:
- Formato
- Movimento
- Classes tradicionais do SDK do Android
Componentes MDC-Android neste codelab
- Formato
O que é necessário
- Conhecimento básico de desenvolvimento para Android.
- Android Studio (faça o download dele aqui, caso ainda não tenha feito)
- Um dispositivo ou emulador Android (disponível no Android Studio)
- O exemplo de código (veja a próxima etapa)
Como você classificaria seu nível de experiência na criação de apps Android?
Está continuando do MDC-103?
Se você concluiu o MDC-103, o código para este codelab já está pronto. Pule para a etapa 3.
Está começando do zero?
Faça o download do app inicial do codelab
O app inicial está localizado no diretório material-components-android-codelabs-104-starter/java
. cd
antes do início.
... ou clone-o do GitHub
Para clonar este codelab do GitHub, execute estes comandos:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 104-starter
Carregar o código inicial no Android Studio
- Quando o assistente de configuração for concluído e a janela Welcome to Android Studio for exibida, clique em Open an existing Android Studio project. Acesse o diretório em que você instalou o exemplo de código e selecione java -> Shrine (ou pesquise shine no computador para abrir o projeto Shrine.
- Aguarde um pouco enquanto o Android Studio cria e sincroniza o projeto, conforme mostrado nos indicadores de atividade na parte inferior da janela.
- Como o SDK do Android ou as ferramentas de compilação não estão presentes, o Android Studio poderá encontrar alguns erros de compilação. Veja um exemplo a seguir. Siga as instruções no Android Studio para instalar/atualizar essas ferramentas e sincronizar o projeto.
Adicionar dependências do projeto
O projeto precisa de uma dependência na Biblioteca de Suporte Android MDC. O exemplo de código transferido por download já precisa ter essa dependência listada, mas recomendamos seguir as etapas abaixo para garantir isso.
- Navegue até o arquivo
build.gradle
do móduloapp
e confira se o blocodependencies
inclui uma dependência no MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Opcional) Se necessário, edite o arquivo
build.gradle
para adicionar as seguintes dependências e sincronizar o projeto.
dependencies { api 'com.google.android.material:material:1.1.0-alpha06' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'com.android.volley:volley:1.1.1' implementation 'com.google.code.gson:gson:2.8.5' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:core:1.1.0' androidTestImplementation 'androidx.test.ext:junit:1.1.0' androidTestImplementation 'androidx.test:runner:1.2.0-alpha05' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05' }
Executar o app inicial
|
Pronto. Você verá o app Shrine em execução no dispositivo.
Um pano de fundo é a superfície traseira mais distante de um app, aparecendo atrás de todos os outros conteúdos e componentes. Ele é composto por duas plataformas: uma camada de fundo, que exibe ações e filtros, e uma camada em primeiro plano, que exibe o conteúdo. Você pode usar um pano de fundo para exibir informações e ações interativas, como filtros de navegação ou conteúdo.
Coalizar o conteúdo da grade
No shr_product_grid_fragment.xml
, adicione o atributo android:visibility="gone"
ao NestedScrollView
para remover temporariamente o conteúdo do produto:
shr_product_grid_fragment.xml
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:elevation="8dp"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
Instalaremos um pano de fundo nessa região. Para não exibir uma divisão entre a barra superior do app e o conteúdo do menu que aparece no pano de fundo, faremos com que o pano de fundo seja da mesma cor da barra de apps superior.
No shr_product_grid_fragment.xml
, adicione o seguinte como o primeiro elemento na FrameLayout
raiz, antes de AppBarLayout
:
shr_product_grid_fragment.xml
<LinearLayout
style="@style/Widget.Shrine.Backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="100dp"
android:paddingBottom="100dp">
</LinearLayout>
Em styles.xml
, adicione este código:
styles.xml
<style name="Widget.Shrine.Backdrop" parent="">
<item name="android:background">?attr/colorAccent</item>
</style>
Muito bem! Você adicionou um lindo pano de fundo à IU do Shrine. Em seguida, adicionaremos um menu.
Adicionar o menu
Um menu é basicamente uma lista de botões de texto. Vamos adicionar um aqui.
Crie um novo layout com o nome shr_backdrop.xml
no seu diretório res -> layout
e adicione o seguinte:
shr_backdrop.xml (link em inglês)
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_featured_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_apartment_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_accessories_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_shoes_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_tops_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_bottoms_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_dresses_label" />
<View
android:layout_width="56dp"
android:layout_height="1dp"
android:layout_margin="16dp"
android:background="?android:attr/textColorPrimary" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_account_label" />
</merge>
Em seguida, adicione esta lista ao LinearLayout
que você acabou de adicionar na shr_product_grid_fragment.xml
usando uma tag <include>
:
shr_product_grid_fragment.xml
<LinearLayout
style="@style/Widget.Shrine.Backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="88dp">
<include layout="@layout/shr_backdrop" />
</LinearLayout>
Crie e execute. A tela inicial ficará assim:
Seu pano de fundo está pronto. Vamos trazer de volta o conteúdo que escondemos anteriormente.
Antes de fazer mudanças no Shrine neste codelab, o conteúdo principal do produto estava localizado na superfície traseira mais distante. Ao adicionar um pano de fundo, agora o conteúdo está mais enfatizado, porque ele aparece na frente dele.
Adicionar uma nova camada
Mostraremos a camada de grade do produto novamente. Remova o atributo android:visibility="gone"
do seu NestedScrollView
:
shr_product_grid_fragment.xml
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:elevation="8dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
Vamos definir o estilo da camada em primeiro plano com um entalhe no canto superior esquerdo. O Material Design se refere a esse tipo de personalização como uma forma. As superfícies do Material Design podem ser exibidas de diferentes formas. As formas dão ênfase e estilo às superfícies e podem ser usadas para expressar o branding. As formas do Material Design podem ter bordas e arestas curvas ou inclinadas para qualquer um dos lados. Elas podem ser simétricas ou irregulares.
Adicionar uma forma
Modifique a forma da grade. Fornecemos um plano de fundo com formato personalizado, mas o formato só é exibido corretamente no Android Marshmallow e em versões mais recentes. Podemos definir o plano de fundo da shr_product_grid_background_shape
no NestedScrollView
somente para Android Marshmallow e versões mais recentes. Primeiro, adicione um id
ao NestedScrollView
para que possamos referenciá-lo no código da seguinte maneira:
shr_product_grid_fragment.xml
<androidx.core.widget.NestedScrollView
android:id="@+id/product_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:elevation="8dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
Em seguida, defina o plano de fundo de forma programática no ProductGridFragment.java
. Adicione a seguinte lógica para definir o segundo plano no fim de onCreateView()
, antes da instrução de retorno:
ProductGridFragment.java (em inglês)
// Set cut corner background for API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
view.findViewById(R.id.product_grid).setBackgroundResource(R.drawable.shr_product_grid_background_shape);
}
Por fim, atualizaremos o recurso de cores productGridBackgroundColor
(também usado pelo plano de fundo de formato personalizado) da seguinte maneira:
colors.xml
<color name="productGridBackgroundColor">#FFFBFA</color>
Criar e executar:
Definimos uma forma personalizada para a interface principal do Shrine. Devido à elevação da superfície, os usuários podem perceber que há algo por trás da camada branca. Vamos adicionar movimento para que os usuários possam ver o que há lá: o menu.
Movimentos são uma forma de dar vida ao app. O movimento pode ser grande e dramático, sutil, mínimo ou estar em qualquer lugar. O tipo de movimento usado precisa ser adequado à situação. Os movimentos aplicados a ações regulares repetidas precisam ser pequenos e sutis para que não ocupem muito tempo regularmente. Outras situações, como a primeira vez que um usuário abre um app, podem ser mais chamativas e podem ajudar a orientar o usuário sobre como usá-lo.
Adicionar um movimento de revelação ao botão de menu
O movimento é a forma na frente, movendo-se diretamente para baixo. Já fornecemos um listener de clique para você, que fará a animação de tradução da página em NavigationIconClickListener.java
. Podemos definir esse listener de clique dentro do método setupToolbar()
do ProductGridFragment.java
:
ProductGridFragment.java (em inglês)
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
O método setUpToolbar()
vai ficar assim:
ProductGridFragment.java (em inglês)
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
}
Crie e execute. Pressione o botão de menu:
Pressionar o ícone do menu de navegação novamente deve esconder o menu.
Ajuste o movimento da camada em primeiro plano
O movimento é uma ótima maneira de expressar sua marca. Vamos ver como é a animação de revelação usando uma curva de tempo diferente.
Atualize seu código em setupToolbar()
no ProductGridFragment.java
para transmitir um interpolador ao listener de clique do ícone de navegação, da seguinte maneira:
ProductGridFragment.java (em inglês)
private void setUpToolbar(View view) { Toolbar toolbar = view.findViewById(R.id.app_bar); AppCompatActivity activity = (AppCompatActivity) getActivity(); if (activity != null) { activity.setSupportActionBar(toolbar); } toolbar.setNavigationOnClickListener(new NavigationIconClickListener( getContext(), view.findViewById(R.id.product_grid), new AccelerateDecelerateInterpolator())); }
Esse é um efeito diferente, certo?
A iconografia da marca também se aplica aos ícones conhecidos. Vamos personalizar o ícone de revelação e mesclá-lo ao nosso título para criar um visual exclusivo para a marca.
Mudar o ícone do botão de menu
Mude o botão do menu para exibir um ícone que inclua um design de losango. Atualize a Barra de Ferramentas no shr_product_grid_fragment.xml
para usar o novo ícone de marca fornecido (shr_branded_menu
) e defina os atributos app:contentInsetStart
e android:padding
para que a barra de ferramentas corresponda melhor às especificações do designer:
shr_product_grid_fragment.xml
<androidx.appcompat.widget.Toolbar android:id="@+id/app_bar" style="@style/Widget.Shrine.Toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:paddingStart="12dp" android:paddingLeft="12dp" android:paddingEnd="12dp" android:paddingRight="12dp" app:contentInsetStart="0dp" app:navigationIcon="@drawable/shr_branded_menu" app:title="@string/shr_app_name" />
Atualize nosso listener de clique novamente em setupToolbar()
no ProductGridFragment.java
para receber drawables para a barra de ferramentas quando o menu estiver aberto e quando ele for fechado, da seguinte maneira:
ProductGridFragment.java (em inglês)
private void setUpToolbar(View view) { Toolbar toolbar = view.findViewById(R.id.app_bar); AppCompatActivity activity = (AppCompatActivity) getActivity(); if (activity != null) { activity.setSupportActionBar(toolbar); } toolbar.setNavigationOnClickListener(new NavigationIconClickListener( getContext(), view.findViewById(R.id.product_grid), new AccelerateDecelerateInterpolator(), getContext().getResources().getDrawable(R.drawable.shr_branded_menu), // Menu open icon getContext().getResources().getDrawable(R.drawable.shr_close_menu))); // Menu close icon }
Criar e executar:
Legal! Quando o pano de fundo puder ser revelado, o ícone do menu do losango será exibido. Quando o menu pode ser ocultado, um ícone "Fechar" é exibido.
Nesses quatro codelabs, você viu como usar os componentes do Material Design para criar experiências do usuário únicas e elegantes que expressam a personalidade e o estilo de uma marca.
Próximas etapas
Este codelab, o MDC-104, encerra essa sequência de codelabs. Para ver ainda mais componentes no MDC-Android, acesse o Catálogo de widgets do Android.
Em um novo desafio deste codelab, modifique o aplicativo Shrine para alterar as imagens do produto exibidas quando uma categoria é selecionada no menu do pano de fundo.
Para saber como conectar esse app ao Firebase para ter um back-end ativo, consulte o Codelab do Firebase para Android.