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 interface 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 com ondulações de tinta. 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 grade cheia de produtos.
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 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?
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/kotlin
. cd
para esse 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. Acesse o diretório em que você instalou o exemplo de código e selecione kotlin -> shrine (ou pesquise shrine no computador) para abrir o projeto Shipping.
- 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 do MDC Android. Provavelmente, o exemplo de código transferido por download já tem essa dependência listada, mas é recomendável seguir as etapas abaixo para garantir.
- Navegue até o arquivo
build.gradle
do móduloapp
e confira se o blocodependencies
inclui uma dependência do 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. 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.
A tela inicial é mostrada quando a página de login é dispensada, com uma tela que diz "Você conseguiu!". Ó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 a navegação para resolver isso.
O Material Design oferece padrões de navegação que garantem uma boa usabilidade. Um dos componentes mais visíveis é 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
Em shr_product_grid_fragment.xml
, exclua o bloco <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>
Seu 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 em 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"
Seu 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 estilizar a barra de apps na parte de cima
Também é possível adicionar botões à extremidade da barra de apps. No Android, eles são chamados de botões de ação. Vamos estilizar a barra de apps na parte de cima e adicionar botões de ação ao menu dela de maneira programática.
Na função onCreateView
de ProductGridFragment.kt
, defina o Toolbar
de activity
para ser usado como um ActionBar
usando setSupportActionBar
. Você pode fazer isso depois que a visualização for criada com o inflater
.
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
Em seguida, logo abaixo do método que acabamos de mudar para configurar a barra de ferramentas, vamos substituir onCreateOptionsMenu
para inflar o conteúdo de shr_toolbar_menu.xml
na barra de ferramentas:
ProductGridFragment.kt
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
Por fim, substitua onCreate()
em ProductGridFragment.kt
e, depois de chamar super()
, chame setHasOptionMenu
com true
:
ProductGridFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
Os snippets de código acima definem a barra de apps do nosso 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: "Pesquisar" e "Filtrar".
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.kt
vai ficar assim:
ProductGridFragment.kt
package com.google.codelabs.mdc.kotlin.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 androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the tool bar
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
override fun 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 elevação usando uma sombra sutil que indica que ela está em uma camada diferente 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. Um card precisa ter uma região para uma imagem, um título e um marcador para texto secundário. Adicione o seguinte em shr_product_grid_fragment.xml
abaixo do 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>
Crie e execute:
Nesta prévia, é possível ver que o card se enquadra na borda esquerda, com cantos arredondados e uma sombra (que representa a elevação dele). O elemento inteiro é chamado de "contêiner". Todos os elementos dentro do contêiner são opcionais, exceto o próprio contêiner.
Você pode adicionar os seguintes elementos a um contêiner: texto de cabeçalho, uma miniatura ou avatar, um texto de subtítulo, divisores e até mesmo botões e ícones. Por exemplo, o card que acabamos de criar contém dois TextView
s (um para o título e outro para o texto secundário) em um LinearLayout
, alinhados à 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 exibi-los como uma coleção em uma grade.
Quando vários cards são exibidos 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 fornecemos para você:
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 carregar e mostrar imagens de um URL) e dois TextViews
.
Em seguida, confira as ProductCardRecyclerViewAdapter
que disponibilizamos para você. Ele está no mesmo pacote que ProductGridFragment
.
ProductCardRecyclerViewAdapter.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
/**
* Adapter used to show a simple grid of products.
*/
class ProductCardRecyclerViewAdapter(private val productList: List<ProductEntry>) : RecyclerView.Adapter<ProductCardViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductCardViewHolder {
val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.shr_product_card, parent, false)
return ProductCardViewHolder(layoutView)
}
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
// TODO: Put ViewHolder binding code here in MDC-102
}
override fun getItemCount(): Int {
return productList.size
}
}
A classe adaptadora acima gerencia o conteúdo da nossa grade. Para determinar o que cada visualização deve fazer com o conteúdo fornecido, vamos escrever o código para onBindViewHolder()
em breve.
No mesmo pacote, você também pode conferir ProductCardViewHolder
. Essa classe armazena as visualizações que afetam o layout do card para que possamos modificá-las mais tarde.
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class ProductCardViewHolder(itemView: View) //TODO: Find and store views from itemView
: RecyclerView.ViewHolder(itemView)
Para configurar nossa grade, primeiro vamos remover o marcador de posição MaterialCardView
de shr_product_grid_fragment.xml
. Em seguida, adicione o componente que representa nossa grade de cards. Neste caso, vamos usar um RecyclerView. Adicione o 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>
Seu 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
em ProductGridFragment.kt
depois de chamar setUpToolbar(view)
e antes da instrução return
:
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(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 definir o gerenciador de layout do RecyclerView
, além de inicializar e definir o adaptador do RecyclerView
.
O arquivo ProductGridFragment.kt
vai ficar assim:
ProductGridFragment.kt
package com.google.codelabs.mdc.kotlin.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 androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))
return view;
}
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
}
Crie e execute:
Os cards estão lá agora! 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 e o preço do produto. Nossa abstração ViewHolder
contém as visualizações de cada card. No ViewHolder
, adicione as três visualizações da seguinte maneira.
ProductCardViewHolder.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.toolbox.NetworkImageView
class ProductCardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var productImage: NetworkImageView = itemView.findViewById(R.id.product_image)
var productTitle: TextView = itemView.findViewById(R.id.product_title)
var productPrice: TextView = itemView.findViewById(R.id.product_price)
}
Atualize o método onBindViewHolder()
no ProductCardRecyclerViewAdapter
para definir o título, o preço e a imagem do produto em cada visualização, conforme mostrado abaixo:
ProductCardRecyclerViewAdapter.kt
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
if (position < productList.size) {
val product = productList[position]
holder.productTitle.text = product.title
holder.productPrice.text = product.price
ImageRequester.setImageFromUrl(holder.productImage, product.url)
}
}
O código acima informa ao adaptador do 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. O ImageRequester
é uma classe que fornecemos para sua conveniência e usa a biblioteca Volley
. Esse é um assunto 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 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
Usamos quatro componentes principais do Material Design da biblioteca MDC-Android: a barra de apps, o card, o campo de texto e o botão. Para conhecer ainda mais componentes, acesse o catálogo do MDC-Android.
Embora nosso app funcione perfeitamente, ele ainda não representa uma marca ou estilo específicos. 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.