MDC-102 Android: struttura e layout dei materiali (Kotlin)

logo_components_color_2x_web_96dp.png

Gli elementi MDC (Material Components) aiutano gli sviluppatori a implementare Material Design. Creata da un team di ingegneri e designer UX di Google, MDC offre decine di componenti dell'interfaccia utente belli e funzionali ed è disponibile per Android, iOS, Web e Flutter.

material.io/develop

Nel codelab MDC-101, hai utilizzato due componenti MDC (Material Components) per creare una pagina di accesso: campi di testo e pulsanti con ondulette inchiostro. Ora espandiamoci su questa base aggiungendo navigazione, struttura e dati.

Cosa imparerai a realizzare

In questo codelab, creerai una schermata Home per un'app chiamata Shrine, un'app di e-commerce che vende abbigliamento e prodotti per la casa. Conterrà:

  • Una barra delle app in alto
  • Un elenco di griglie pieno di prodotti

Componenti di MDC-Android in questo codelab

  • Layout barraBar
  • MaterialCardView

Che cosa ti serve

  • Conoscenza di base dello sviluppo di Android
  • Android Studio (scaricalo qui se non lo hai già)
  • Un emulatore o dispositivo Android (disponibile tramite Android Studio)
  • Il codice di esempio (vedi il passaggio successivo)

Come giudichi il tuo livello di esperienza nella creazione di app Android?

Principiante Intermedio Esperto

Vuoi continuare da MDC-101?

Se hai completato MDC-101, il tuo codice deve essere preparato per questo codelab. Vai al passaggio 3: aggiungi una barra delle app in alto.

È tutto da zero?

Scarica l'app del codelab per iniziare

Scarica l'app iniziale

L'app iniziale si trova nella directory material-components-android-codelabs-102-starter/kotlin. Assicurati di cd nella directory prima di iniziare.

...o clonarlo da GitHub

Per clonare questo codelab da GitHub, esegui i comandi seguenti:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 102-starter

Carica il codice di avvio in Android Studio

  1. Una volta terminata la configurazione guidata e mostrata la finestra Ti diamo il benvenuto in Android Studio, fai clic su Apri un progetto Android Studio esistente. Passa alla directory in cui hai installato il codice di esempio e seleziona kotlin -> santuario(o cerca sul tuo computer santo) per aprire il progetto di spedizione.
  2. Aspetta un momento che Android Studio crei e sincronizzi il progetto, come mostrato dagli indicatori di attività nella parte inferiore della finestra di Android Studio.
  3. A questo punto, Android Studio potrebbe causare alcuni errori di generazione perché non disponi dell'SDK Android o di strumenti di sviluppo come quello mostrato di seguito. Segui le istruzioni in Android Studio per installarle/aggiornarle e sincronizzare il tuo progetto.

Aggiungi le dipendenze del progetto

Il progetto richiede una dipendenza dalla libreria di assistenza Android MDC. Il codice di esempio che hai scaricato deve avere già questa dipendenza, ma è consigliabile farlo seguendo questi passaggi.

  1. Passa al file build.gradle del modulo app e assicurati che il blocco dependencies includa una dipendenza su MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (Facoltativo) Se necessario, modifica il file build.gradle per aggiungere le seguenti dipendenze e sincronizzare il progetto.
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'
}

Esegui l'app iniziale

  1. Assicurati che la configurazione della build a sinistra del pulsante Esegui/Riproduci sia app.
  2. Premi il pulsante verde Esegui/Riproduci per creare ed eseguire l'app.
  3. Se nella finestra Seleziona target di deployment è già presente un dispositivo Android, vai al passaggio 8. In caso contrario, fai clic su Crea nuovo dispositivo virtuale.
  4. Nella schermata Seleziona hardware, seleziona un dispositivo telefonico, ad esempio Pixel 2, quindi fai clic su Avanti.
  5. Nella schermata System System (Immagine di sistema), seleziona una versione recente di Android, preferibilmente il livello API più alto. Se non è installato, fai clic sul link Scarica visualizzato e completa il download.
  6. Tocca Avanti.
  7. Nella schermata Android Virtual Device (AVD), lascia le impostazioni invariate e fai clic su Fine.
  8. Seleziona un dispositivo Android dalla finestra di dialogo del target di deployment.
  9. Fai clic su OK.
  10. Android Studio crea l'app, ne esegue il deployment e la apre automaticamente sul dispositivo di destinazione.

Operazione riuscita. Dovresti vedere la pagina di accesso del santuario dal codelab MDC-101.

Ora che la schermata di accesso ha un aspetto positivo, usiamo l'app con alcuni prodotti.

La schermata Home viene mostrata quando la pagina di accesso viene ignorata, con una schermata che dice "Ce l'hai fatta!". Fantastico! Tuttavia, ora l'utente non ha alcuna azione da intraprendere o non ha alcuna idea sulla posizione in cui si trova nell'app. Per aiutarti, è ora di aggiungere la navigazione.

Material Design offre schemi di navigazione che garantiscono un elevato grado di usabilità. Uno dei componenti più visibili è una barra delle app in alto.

Per fornire la navigazione e consentire agli utenti di accedere rapidamente ad altre azioni, aggiungi una barra delle app in alto.

Aggiungere un widget AppBar

In shr_product_grid_fragment.xml, elimina il blocco <LinearLayout> contenente "l'hai fatto!". TextView e sostituiscilo con il seguente:

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>

shr_product_grid_fragment.xml dovrebbe avere il seguente aspetto:

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>

Molte barre delle app hanno un pulsante accanto al titolo. Aggiungiamo un'icona del menu nella nostra.

Aggiungere un'icona di navigazione

Mentre sei ancora in shr_product_grid_fragment.xml, aggiungi quanto segue al componente XML Toolbar che hai appena aggiunto al tuo layout:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

Il tuo shr_product_grid_fragment.xml dovrebbe avere il seguente aspetto:

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>

Aggiungi pulsanti di azione e stile per la barra dell'app in alto

Puoi anche aggiungere pulsanti sul lato finale della barra dell'app. In Android, questi sono chiamati pulsanti di azione. Stileremo la barra dell'app in alto e aggiungeremo i pulsanti di azione al menu in modo programmatico.

Nella funzione onCreateView di ProductGridFragment.kt, imposta Toolbar di activity da utilizzare come ActionBar utilizzando setSupportActionBar. Puoi eseguire questa operazione dopo aver creato la vista con 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;
}

In seguito, direttamente sotto il metodo che abbiamo appena modificato per configurare la barra degli strumenti, esegui l'override di onCreateOptionsMenu per aumentare il contenuto di shr_toolbar_menu.xml nella barra degli strumenti:

ProductGridFragment.kt

override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
   super.onCreateOptionsMenu(menu, menuInflater)
}

Infine, esegui l'override di onCreate() in ProductGridFragment.kt e, dopo aver chiamato super(), chiama setHasOptionMenu con true:

ProductGridFragment.kt

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setHasOptionsMenu(true)
}

Gli snippet di codice riportati sopra impostano la barra dell'app del nostro layout XML come barra delle azioni per questa attività. Il callback onCreateOptionsMenu indica all'attività come utilizzare il menu. In questo caso, verranno inserite le voci di menu di R.menu.shr_toolbar_menu nella barra dell'app. Il file di menu contiene due voci: "Ricerca" e "Filtro".

menu_barra_shr.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>

Dopo le modifiche, il file ProductGridFragment.kt dovrebbe avere il seguente aspetto:

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)
   }
}

Crea ed esegui. La schermata Home dovrebbe avere il seguente aspetto:

Ora la barra degli strumenti presenta un'icona di navigazione, un titolo e due icone di azione sul lato destro. Anche la barra degli strumenti mostra un'elevazione utilizzando una leggera ombra che mostra un livello diverso rispetto ai contenuti.

Ora che la nostra app ha una struttura, decidiamo come organizzare i contenuti inserendoli in schede.

Aggiungere una carta

Per iniziare, aggiungi una scheda sotto la barra superiore dell'app. Una scheda deve avere un'area geografica per un'immagine, un titolo ed un'etichetta per il testo secondario. Aggiungi quanto segue in shr_product_grid_fragment.xml sotto 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>

Crea ed esegui:

In questa anteprima puoi vedere che la scheda è inserita dal bordo sinistro e contiene angoli arrotondati e un'ombra (che indica l'altezza della scheda). L'intero elemento è chiamato "container." A parte il contenitore, tutti gli elementi al suo interno sono facoltativi.

Puoi aggiungere i seguenti elementi a un contenitore: testo dell'intestazione, miniatura o avatar, testo secondario, divisori e persino pulsanti e icone. La scheda appena creata, ad esempio, contiene due TextView (uno per il titolo e uno per il testo secondario) in un elemento LinearLayout, allineato in fondo alla scheda.

In genere le schede vengono mostrate in una raccolta con altre schede. Nella sezione successiva di questo codelab, le illustreremo come raccolte in una griglia.

Se in una schermata sono presenti più schede, queste sono raggruppate in una o più raccolte. Le schede in una griglia sono complanari, il che significa che condividono la stessa altezza a riposo (a meno che non siano state raccolte o trascinate, ma non questa verrà trattata in questo codelab).

Configurare la griglia delle schede

Dai un'occhiata al file shr_product_card.xml che ti abbiamo fornito:

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>

Il layout di questa scheda contiene una scheda con un'immagine (in questo caso, NetworkImageView, che ci consente di caricare e mostrare immagini di un URL), e due TextViews.

Ora diamo un'occhiata al ProductCardRecyclerViewAdapter che ti abbiamo fornito. È nello stesso pacchetto di 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
   }
}

La classe dell'adattatore sopra riportata gestisce i contenuti della nostra griglia. Scriviamo il codice per la pagina onBindViewHolder() al fine di determinare quale deve essere l'aspetto di ogni visualizzazione.

Anche nello stesso pacchetto puoi anche dare un'occhiata a ProductCardViewHolder. Questo corso memorizza le visualizzazioni che influiscono sul layout della scheda, in modo da poterle modificare in un secondo momento.

ProductCardViewHolder.kt

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)

Per impostare la griglia, vogliamo prima rimuovere il segnaposto MaterialCardView da shr_product_grid_fragment.xml. A questo punto, devi aggiungere il componente che rappresenta la nostra griglia di schede. In questo caso useremo una RecyclerView. Aggiungi il componente RecyclerView al shr_product_grid_fragment.xml sotto il 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>

Il tuo shr_product_grid_fragment.xml dovrebbe avere il seguente aspetto:

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>

Infine, in onCreateView(), aggiungi il codice di inizializzazione di RecyclerView a ProductGridFragment.kt dopo aver chiamato setUpToolbar(view) e prima dell'istruzione 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;
}

Lo snippet di codice riportato sopra contiene i passaggi per l'inizializzazione necessari per configurare un RecyclerView. Include l'impostazione del gestore di layout di RecyclerView, l'inizializzazione e l'impostazione dell'adattatore per RecyclerView.

Il tuo file ProductGridFragment.kt dovrebbe avere il seguente aspetto:

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)
   }
}

Crea ed esegui:

Le carte sono lì! Non mostrano ancora nulla, quindi aggiungiamo alcuni dati di prodotto.

Aggiungere immagini e testo

Per ogni scheda, aggiungi un'immagine, il nome del prodotto e un prezzo. La nostra astrazione ViewHolder contiene le visualizzazioni per ogni scheda. Nel nostro ViewHolder, aggiungi le tre viste come indicato di seguito.

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)
}

Aggiorna il metodo onBindViewHolder() in ProductCardRecyclerViewAdapter per impostare il titolo, il prezzo e l'immagine del prodotto per ogni visualizzazione del prodotto, come mostrato di seguito:

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)
   }
}

Il codice riportato sopra indica al nostro adattatore di RecyclerView che cosa fare con ciascuna scheda, utilizzando un ViewHolder.

In questo modo, la funzione imposta i dati di testo su ogni TextView di ViewHolder e chiama un ImageRequester per ricevere un'immagine da un URL. ImageRequester è una classe che abbiamo fornito per tua comodità e utilizza la libreria Volley, ovvero un argomento che non rientra nell'ambito di questo codelab, ma non esitare a esplorare il codice per conto tuo.

Crea ed esegui:

I nostri prodotti vengono visualizzati nell'app.

La nostra app ha un flusso di base che porta l'utente dalla schermata di accesso a una schermata Home, dove è possibile visualizzare i prodotti. In poche righe di codice abbiamo aggiunto una barra superiore dell'app con un titolo, tre pulsanti e una griglia di schede per presentare i contenuti dell'app. Ora la nostra schermata Home è semplice e funzionale, con una struttura di base e contenuti utili.

Passaggi successivi

Con la barra superiore, la scheda, il campo di testo e il pulsante superiore, abbiamo utilizzato quattro componenti di base di Material Design presenti nella libreria MDC-Android. Puoi esplorare altri componenti visitando il catalogo MDC-Android.

Sebbene sia completamente funzionante, la nostra app non esprime ancora alcun brand o stile particolare. In MDC-103: Material Design Theming with Color, Shape, Elevation and Type (Personalizza il tema dei materiali con il colore, la forma, l'elevazione e il tipo), personalizza lo stile di questi componenti per esprimere un brand vivace e moderno.

Sono riuscito a completare questo codelab con un tempo e con un impegno ragionevoli

Totalmente d'accordo D'accordo Neutro In disaccordo Totalmente in disaccordo

Vorrei continuare a utilizzare i componenti materiali in futuro

Totalmente d'accordo Totalmente d'accordo Neutro Totalmente in disaccordo Totalmente in disaccordo