1. Introdução
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 apresentam dezenas de componentes de interface bonitos e funcionais e estão 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 em grade de produtos
Componentes 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 (confira a próxima etapa)
Como você classificaria seu nível de experiência na criação de apps Android?
2. Configurar o ambiente de desenvolvimento
Está continuando do MDC-101?
Se você concluiu o MDC-101, o código para este codelab já está pronto. Você pode pular 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
. Insira cd
nesse diretório antes de começar.
... 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. Navegue até o diretório em que você instalou o exemplo de código e selecione java -> Cymbal (ou procure shrine no seu computador) para abrir o projeto do 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 MDC Android. O exemplo de código transferido por download já tem essa dependência listada, mas é uma boa prática seguir as etapas abaixo para ter certeza.
- Navegue até o arquivo
build.gradle
do móduloapp
e verifique 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 dependências a seguir 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. A página de login do Shrine do codelab MDC-101 vai aparecer.
Agora que a tela de login está pronta, vamos preencher o app com alguns produtos.
3. Adicionar uma barra de apps superior
A tela inicial é revelada quando a página de login é dispensada, com uma tela que diz "You did it!". Ótimo, Mas agora o usuário não tem mais nada a fazer nem sabe onde está no app. Para ajudar com isso, vamos adicionar a navegação.
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 na parte de cima.
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
Em shr_product_grid_fragment.xml
, exclua a tag <LinearLayout>
que contém a mensagem "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
vai ficar assim:
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 seu layout:
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
O shr_product_grid_fragment.xml
vai ficar assim:
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 final da barra de apps. No Android, são chamados de botões de ação.
Vamos estilizar a barra de apps superior e adicionar botões de ação ao menu de forma programática.
Primeiro, vamos criar um método para configurar a barra de ferramentas. O método precisa receber uma referência à barra de ferramentas usando o id
e também uma 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
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 onCreateOptionsMenu
para inflar o conteúdo de shr_toolbar_menu.xml
na barra de ferramentas:
ProductGridFragment.java
@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
@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()
a ProductGridFragment.java
. No corpo do método, defina o parâmetro de setHasOptionMenu
como true
.
O método ficará assim:
ProductGridFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
O código acima define a barra de apps do layout XML como a barra de ações dessa atividade. O callback onCreateOptionsMenu
informa à atividade o que usar como menu. Nesse caso, ele vai colocar os itens de menu de R.menu.shr_toolbar_menu
na barra de apps.
O arquivo de menu contém dois itens: "Search" e "Filter".
shr_toolbar_menu.xml
<?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, o arquivo ProductGridFragment.java
ficará assim:
ProductGridFragment.java
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 mostra a elevação usando uma sombra sutil, que mostra que a imagem está em uma camada diferente da do conteúdo.
4. Adicionar um cartão
Agora que nosso app tem uma estrutura, 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. Um card precisa ter uma região para uma imagem, um título e um rótulo para o texto secundário.
Em shr_product_grid_fragment.xml
, adicione o seguinte abaixo de 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 prévia, é possível ver que o card se enquadra na borda esquerda da tela, tem cantos arredondados e uma sombra (que representa a elevação dele). Essa área é chamada de "contêiner". Todos os elementos dentro dele são opcionais, exceto o contêiner em si.
Você pode adicionar os seguintes elementos a um contêiner: texto do cabeçalho, miniatura ou avatar, texto de subtítulo, divisores e até mesmo botões e ícones. O card que acabamos de criar, por exemplo, contém dois TextView
s (um para o título e outro para o texto secundário) em um LinearLayout
, alinhados na parte de baixo do card.
Os cards geralmente são exibidos com outros em uma coleção. Na próxima seção deste codelab, vamos exibir os itens como uma coleção em uma grade.
5. Criar uma grade de cards
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, ou seja, compartilham a mesma elevação de repouso (a menos que sejam retirados ou arrastados, mas não vamos abordar isso neste codelab).
Configurar a grade de cards
Confira o arquivo shr_product_card.xml
que disponibilizamos:
shr_product_card.xml
<?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>
Esse layout de card contém um card com uma imagem (neste caso, um NetworkImageView
, que permite incluir imagens de um URL) e dois TextViews
.
Em seguida, consulte o ProductCardRecyclerViewAdapter
que fornecemos para você. Ele está no mesmo pacote que ProductGridFragment
.
ProductCardRecyclerViewAdapter.java
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 do adaptador acima gerencia o conteúdo da grade. Para determinar o que cada visualização precisa fazer com o próprio conteúdo, vamos programar em breve o código para onBindViewHolder()
.
No mesmo pacote, também é possível dar uma olhada em ProductCardViewHolder
. Essa classe armazena as visualizações que afetam o layout do card para que possamos 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 remova o marcador de posição 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
vai ficar assim:
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, em 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
@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 um RecyclerView
. Isso inclui a configuração do gerenciador de layout do RecyclerView
, além da inicialização e configuração do adaptador do RecyclerView
.
O arquivo ProductGridFragment.java
vai ficar assim:
ProductGridFragment.java
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 lá! Eles ainda não mostram nada, então vamos adicionar alguns dados de produtos.
Adicionar imagens e texto
Para cada card, adicione uma imagem, o nome do produto e o preço. Nossa abstração ViewHolder
armazena as visualizações de cada card. No ViewHolder
, adicione as três visualizações da seguinte maneira:
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 da RecyclerView
, no ViewHolder,
, atualize o método onBindViewHolder()
para definir as informações em cada visualização:
ProductCardRecyclerViewAdapter.java
@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 do RecyclerView
o que fazer com cada cartão, usando um ViewHolder
.
Aqui, ele define os dados de texto em cada TextView
do ViewHolder
e chama um ImageRequester
para receber uma imagem de um URL. A ImageRequester
é uma classe que disponibilizamos para sua conveniência e usa a biblioteca Volley
. Esse é um tema fora do escopo deste codelab, mas fique à vontade para explorar o código por conta própria.
Crie e execute:
Agora, nossos produtos estão sendo exibido perfeitamente no app!
6. Recapitulação
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 e 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
Com a barra de apps, o card, o campo de texto e o botão na parte de cima, usamos quatro componentes principais do Material Design da biblioteca MDC-Android. Acesse o catálogo de componentes do MDC-Android para conferir mais componentes.
Embora nosso app funcione perfeitamente, ele ainda não representa 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.