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-101, você usou dois componentes do Material Design (MDC) para criar uma página de login: campos de texto e botões. Agora, vamos nos aprofundar nessa base adicionando navegação, estrutura e dados.
O que você criará
Neste codelab, você criará uma tela inicial para o app Shrine, um app de comércio eletrônico que vende roupas e artigos domésticos. Ele conterá:
- Uma barra de apps superior.
- Uma lista de produtos em grade
Componentes do MDC-Android neste codelab
- AppBarLayout
- MaterialCardView
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-101?
Se você concluiu o MDC-101, o código para este codelab já está pronto. Pule para a etapa 3: Adicionar uma barra de apps superior.
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-102-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 102-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á a página de login do Shrine do codelab MDC-101.
Agora que a tela de login está pronta, vamos preencher o app com alguns produtos.
A tela inicial é revelada quando a página de login é dispensada, com uma tela mostrando "quot;Você conseguiu!". Isso é ótimo. Mas agora o usuário não pode realizar nenhuma outra ação e também não sabe em que parte do app está. Vamos adicionar navegação para ajudar você com isso.
O Material Design oferece padrões de navegação que garantem uma boa usabilidade. Um dos componentes de navegação mais importantes é a barra de apps superior.
Para que os usuários possam navegar e ter acesso rápido a outras ações, vamos adicionar uma barra de apps superior.
Adicionar um widget AppBar
No arquivo shr_product_grid_fragment.xml
, exclua a tag <LinearLayout>
que contém o texto ""Você conseguiu!" TextView
e substitua pelo seguinte:
shr_product_grid_fragment.xml
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
O shr_product_grid_fragment.xml
será semelhante a este:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
Muitas barras de apps têm um botão ao lado do título. Vamos adicionar um ícone de menu ao nosso.
Adicionar um ícone de navegação
Ainda no shr_product_grid_fragment.xml
, adicione o seguinte ao componente XML Toolbar
(que você acabou de adicionar ao layout):
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
O shr_product_grid_fragment.xml
será semelhante a este:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
Adicionar botões de ação e definir o estilo da barra de apps superior
Também é possível adicionar botões ao lado final da barra de apps. No Android, eles são chamados de botões de ação.
Vamos personalizar a barra de apps superior e adicionar botões de ação ao menu dela de forma programática.
Primeiro, vamos criar um método para configurar a barra de ferramentas. O método precisa conseguir uma referência à barra de ferramentas usando o id
, além de fazer referência à atividade usando getActivity()
. Se a atividade não for nula, defina o Toolbar
para ser usado como um ActionBar
usando setSupportActionBar
:
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);
}
}
Em seguida, logo abaixo do método setUpToolbar
que acabamos de adicionar, vamos substituir o onCreateOptionsMenu
para inflar o conteúdo do shr_toolbar_menu.xml
na barra de ferramentas:
ProductGridFragment.java (em inglês)
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
Agora, adicione uma chamada ao método setUpToolbar
que adicionamos ao conteúdo do método onCreateView()
com o seguinte:
ProductGridFragment.java (em inglês)
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
Por fim, adicione um método onCreate()
à ProductGridFragment.java
. No corpo do método, defina o parâmetro de setHasOptionMenu
como true
.
O método será assim:
ProductGridFragment.java (em inglês)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
O código acima define a barra de apps do nosso layout XML como a barra de ações da atividade. O callback onCreateOptionsMenu
informa à atividade o que usar como menu. Nesse caso, os itens de menu do R.menu.shr_toolbar_menu
serão colocados na barra de apps.
O arquivo de menu contém dois itens: "Pesquisa" e "Filtro".
shr_Toolbar_menu.xml (link em inglês)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/shr_search"
android:title="@string/shr_search_title"
app:showAsAction="always" />
<item
android:id="@+id/filter"
android:icon="@drawable/shr_filter"
android:title="@string/shr_filter_title"
app:showAsAction="always" />
</menu>
Depois dessas mudanças, seu arquivo ProductGridFragment.java
ficará assim:
ProductGridFragment.java (em inglês)
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
Crie e execute. A tela inicial ficará assim:
Agora a barra de ferramentas tem um ícone de navegação, um título e dois ícones de ação no lado direito. A barra de ferramentas também exibe a elevação usando uma sombra sutil, que os mostra em uma camada diferente da do conteúdo.
Agora que nosso app tem uma estrutura básica, vamos organizar o conteúdo colocando-o em cards.
Adicionar um cartão
Para começar, vamos adicionar um card abaixo da barra de apps superior. O cartão precisa ter a região de uma imagem, um título e um rótulo para texto secundário.
Em shr_product_grid_fragment.xml
, adicione o código a seguir a AppBarLayout
:
shr_product_grid_fragment.xml
<com.google.android.material.card.MaterialCardView
android:layout_width="160dp"
android:layout_height="180dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="70dp"
app:cardBackgroundColor="?attr/colorPrimaryDark"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Criar e executar:
Nesta visualização, é possível ver que o card se enquadra na borda esquerda da tela e tem cantos arredondados e uma sombra (que representa a elevação dele). Toda a área é chamada de "container." Com exceção do próprio contêiner, todos os elementos dentro dele são opcionais.
Você pode adicionar os seguintes elementos a um contêiner: texto do cabeçalho, miniatura ou avatar, subtítulo, divisores e até mesmo botões e ícones. O card que criamos, por exemplo, contém dois TextView
s (um para o título e um para o texto secundário) em um LinearLayout
, alinhado à parte inferior do card.
Os cards geralmente são exibidos com outros em uma coleção. Na próxima seção deste codelab, eles serão dispostos em uma grade.
Quando há vários cards em uma tela, eles são agrupados em uma ou mais coleções. Os cards em uma grade são coplanares, o que significa que eles compartilham a mesma elevação de repouso (a menos que sejam extraídos ou arrastados, mas isso não será abordado neste codelab).
Configurar a grade de cards
Confira o arquivo shr_product_card.xml
que fornecemos:
shr_product_card.xml (link em inglês)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/product_image"
android:layout_width="match_parent"
android:layout_height="@dimen/shr_product_card_image_height"
android:background="?attr/colorPrimaryDark"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
O layout desse card contém um card com uma imagem (aqui, um NetworkImageView
, que permite incluir imagens de um URL), e dois TextViews
.
Depois, confira o ProductCardRecyclerViewAdapter
que fornecemos para você. Está no mesmo pacote que ProductGridFragment
.
ProductCardRecyclerViewAdapter.java (link em inglês)
package com.google.codelabs.mdc.java.shrine;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.codelabs.mdc.java.shrine.network.ImageRequester;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
import java.util.List;
/**
* Adapter used to show a simple grid of products.
*/
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {
private List<ProductEntry> productList;
private ImageRequester imageRequester;
ProductCardRecyclerViewAdapter(List<ProductEntry> productList) {
this.productList = productList;
imageRequester = ImageRequester.getInstance();
}
@NonNull
@Override
public ProductCardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.shr_product_card, parent, false);
return new ProductCardViewHolder(layoutView);
}
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
// TODO: Put ViewHolder binding code here in MDC-102
}
@Override
public int getItemCount() {
return productList.size();
}
}
A classe de adaptador acima gerencia o conteúdo da nossa grade. Para determinar o que cada visualização deve fazer com o conteúdo fornecido, em breve criaremos o código para onBindViewHolder()
.
No mesmo pacote, também é possível analisar ProductCardViewHolder
. Essa classe armazena as visualizações que afetam o layout do card. Assim, poderemos modificá-las mais tarde.
ProductCardViewHolder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
// TODO: Find and store views from itemView
}
}
Para configurar nossa grade, primeiro precisamos remover o marcador MaterialCardView
de shr_product_grid_fragment.xml
. Em seguida, adicione o componente que representa nossa grade de cards. Nesse caso, adicione um componente RecyclerView ao shr_product_grid_fragment.xml
abaixo do componente XML AppBarLayout
:
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:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
O shr_product_grid_fragment.xml
será semelhante a este:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
</FrameLayout>
Por fim, no onCreateView()
, adicione o código de inicialização RecyclerView
ao ProductGridFragment.java
depois de chamar setUpToolbar(view)
e antes da instrução return
:
ProductGridFragment.java (em inglês)
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
O snippet de código acima contém as etapas de inicialização necessárias para configurar uma RecyclerView
. Isso inclui a configuração do gerenciador de layout do RecyclerView
, mais a inicialização e a definição do adaptador do RecyclerView
.
Seu arquivo ProductGridFragment.java
ficará assim:
ProductGridFragment.java (em inglês)
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
Crie e execute.
Os cards já estão disponíveis. Ainda não há nada. Por isso, vamos adicionar alguns dados do produto.
Adicionar imagens e textos
Para cada card, adicione uma imagem, um nome do produto e um preço. A abstração ViewHolder
contém as visualizações de cada card. Em ViewHolder
, adicione as três visualizações da seguinte forma:
ProductCardViewHolder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.volley.toolbox.NetworkImageView;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView productImage;
public TextView productTitle;
public TextView productPrice;
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productPrice = itemView.findViewById(R.id.product_price);
}
}
No adaptador RecyclerView
de ViewHolder,
, atualize o método onBindViewHolder()
para definir as informações em cada visualização:
ProductCardRecyclerViewAdapter.java (link em inglês)
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
if (productList != null && position < productList.size()) {
ProductEntry product = productList.get(position);
holder.productTitle.setText(product.title);
holder.productPrice.setText(product.price);
imageRequester.setImageFromUrl(holder.productImage, product.url);
}
}
O código acima informa ao adaptador RecyclerView
o que fazer com cada card, usando um ViewHolder
.
Aqui, ele define os dados de texto em cada um dos TextView
s do ViewHolder
e chama um ImageRequester
para receber uma imagem de um URL. A ImageRequester
é uma classe fornecida por sua conveniência e usa a biblioteca Volley
(esse é um tópico fora do escopo deste codelab, mas fique à vontade para explorar o código por conta própria).
Criar e executar:
Agora, nossos produtos estão sendo exibidos no app.
Nosso app tem um fluxo básico que leva o usuário da tela de login a uma tela inicial, onde os produtos são exibidos. Em apenas algumas linhas de código, adicionamos uma barra de apps superior com um título e três botões, além de uma grade de cards para apresentar o conteúdo do nosso app. Nossa tela inicial agora é simples e funcional, com uma estrutura básica e um conteúdo acionável.
Próximas etapas
Agora, com a barra de apps superior, o card, o campo de texto e o botão, usamos quatro componentes principais do Material Design na biblioteca MDC-Android. Conheça ainda mais componentes nos componentes do MDC-Android Catalog no MDC para Android.
Embora seja totalmente funcional, nosso app ainda não expressa uma marca específica. No codelab MDC-103: temas do Material Design usando cor, forma, elevação e tipo, vamos personalizar o estilo desses componentes para representar uma marca vibrante e moderna.