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

1. Introduzione

logo_components_color_2x_web_96dp.png

I componenti Material (MDC) aiutano gli sviluppatori a implementare Material Design. Creati da un team di ingegneri e progettisti UX di Google, i componenti MDC includono decine di componenti UI belli e funzionali e sono disponibili per Android, iOS, web e Flutter.material.io/develop

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

Cosa creerai

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

  • Una barra dell'app in alto
  • Un elenco a griglia pieno di prodotti

249db074eff043f4.png

Componenti MDC-Android in questo codelab

  • AppBarLayout
  • MaterialCardView

Che cosa ti serve

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

Come valuteresti il tuo livello di esperienza nella creazione di app per Android?

Principiante Intermedio Esperto

2. Configurazione dell'ambiente di sviluppo

Continui da MDC-101?

Se hai completato MDC-101, il codice dovrebbe essere pronto per questo codelab. Vai al passaggio 3: Aggiungi una barra dell'app in alto.

Inizi da zero?

Scarica l'app del codelab di base

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

...o clonala da GitHub

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

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 completata la procedura guidata di configurazione e visualizzata la finestra Welcome to Android Studio (Benvenuto in Android Studio), fai clic su Open an existing Android Studio project (Apri un progetto Android Studio esistente). Vai alla directory in cui hai installato il codice campione e seleziona kotlin -> shrine (o cerca shrine sul computer) per aprire il progetto Shipping.
  2. Attendi qualche istante che Android Studio crei e sincronizzi il progetto, come indicato dagli indicatori di attività nella parte inferiore della finestra di Android Studio.
  3. A questo punto, Android Studio potrebbe generare alcuni errori di compilazione perché mancano l'SDK Android o gli strumenti di compilazione, come quello mostrato di seguito. Segui le istruzioni in Android Studio per installare/aggiornare questi elementi e sincronizzare il progetto.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

Aggiungi le dipendenze del progetto

Il progetto richiede una dipendenza dalla libreria di supporto MDC Android. Il codice campione che hai scaricato dovrebbe già includere questa dipendenza, ma è buona norma eseguire i passaggi seguenti per assicurarti che sia così.

  1. Vai al file build.gradle del modulo app e assicurati che il blocco dependencies includa una dipendenza da 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 di base

  1. Assicurati che la configurazione di compilazione a sinistra del pulsante Esegui / Riproduci sia app.
  2. Premi il pulsante Esegui / Riproduci verde per compilare ed eseguire l'app.
  3. Nella finestra Select Deployment Target (Seleziona target di deployment), se hai già un dispositivo Android elencato nei dispositivi disponibili, vai al passaggio 8. In caso contrario, fai clic su Create New Virtual Device (Crea nuovo dispositivo virtuale).
  4. Nella schermata Select Hardware (Seleziona hardware), seleziona un dispositivo smartphone, ad esempio Pixel 2, quindi fai clic su Next (Avanti).
  5. Nella schermata System Image (Immagine di sistema), seleziona una versione recente di Android, preferibilmente il livello API più alto. Se non è installata, fai clic sul link Download (Scarica) visualizzato e completa il download.
  6. Fai clic su Next (Avanti).
  7. Nella schermata Android Virtual Device (AVD) , lascia le impostazioni così come sono e fai clic su Finish.
  8. Seleziona un dispositivo Android nella finestra di dialogo del target di deployment.
  9. Fai clic su Ok.
  10. Android Studio compila l'app, la esegue il deployment e la apre automaticamente sul dispositivo di destinazione.

Operazione riuscita. Dovresti visualizzare la pagina di accesso di Shrine del codelab MDC-101.

4cb0c218948144b4.png

Ora che la schermata di accesso è perfetta, aggiungiamo alcuni prodotti all'app.

3. Aggiungi una barra dell'app in alto

La schermata Home viene visualizzata quando la pagina di accesso viene chiusa, con una schermata che indica "You did it!" (Ce l'hai fatta!). Fantastico. Ma ora l'utente non ha azioni da intraprendere o non sa dove si trova nell'app. Per risolvere questo problema, è il momento di aggiungere la navigazione.

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

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

Aggiungi un widget AppBar

In shr_product_grid_fragment.xml, elimina il blocco <LinearLayout> contenente "You did it!" 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>

Il file shr_product_grid_fragment.xml dovrebbe ora 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 dell'app hanno un pulsante accanto al titolo. Aggiungiamo un'icona del menu alla nostra.

Aggiungi 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 layout:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

Il file 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 applica uno stile alla barra dell'app in alto

Puoi anche aggiungere pulsanti alla fine della barra dell'app. In Android, questi pulsanti sono chiamati pulsanti di azione. Applicheremo uno stile alla barra dell'app in alto e aggiungeremo i pulsanti di azione al relativo menu a livello di programmazione.

Nella funzione onCreateView di ProductGridFragment.kt, imposta la Toolbar dell'activity da utilizzare come ActionBar utilizzando setSupportActionBar. Puoi farlo dopo che la visualizzazione è stata creata 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;
}

Poi, direttamente sotto il metodo che abbiamo appena modificato per configurare la barra degli strumenti, sostituiamo onCreateOptionsMenu per eseguire l'inflate dei contenuti 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, sostituisci 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 dal layout XML come barra delle azioni per questa attività. Il callback onCreateOptionsMenu indica all'attività cosa utilizzare come menu. In questo caso, inserirà le voci di menu da R.menu.shr_toolbar_menu nella barra dell'app. Il file di menu contiene due voci: "Search" (Cerca) e "Filter" (Filtra).

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>

Dopo queste 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:

d04e8aa3b27f4754.png

Ora la barra degli strumenti ha un'icona di navigazione, un titolo e due icone di azione sul lato destro. La barra degli strumenti mostra anche l'elevazione utilizzando un'ombra discreta che indica che si trova su un livello diverso rispetto ai contenuti.

4. Aggiungi una scheda

Ora che la nostra app ha una struttura, organizziamo i contenuti inserendoli nelle carte.

Aggiungi una scheda

Iniziamo aggiungendo una scheda sotto la barra dell'app in alto. Una scheda deve avere una regione per un'immagine, un titolo e 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:

f6184a55ccb5f920.png

In questa anteprima, puoi vedere che la carta è inserita dal bordo sinistro, ha angoli arrotondati e un'ombra (che esprime l'elevazione della carta). L'intero elemento è chiamato "contenitore". Oltre al contenitore, tutti gli elementi al suo interno sono facoltativi.

Puoi aggiungere i seguenti elementi a un contenitore: testo dell'intestazione, una miniatura o un avatar, testo del sottotitolo, divisori e persino pulsanti e icone. La carta che abbiamo appena creato, ad esempio, contiene due TextView (uno per il titolo e uno per il testo secondario) in un LinearLayout , allineato alla parte inferiore della carta.

Le carte vengono in genere mostrate in una raccolta con altre carte. Nella sezione successiva di questo codelab, le disporremo come una raccolta in una griglia.

5. Crea una griglia di carte

Quando sono presenti più schede in una schermata, vengono raggruppate in una o più raccolte. Le carte in una griglia sono complanari, il che significa che condividono la stessa elevazione di riposo (a meno che non vengano raccolte o trascinate, ma non tratteremo questo argomento in questo codelab).

Configura la griglia di carte

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>

Questo layout della carta contiene una carta con un'immagine (in questo caso, un NetworkImageView, che ci consente di caricare e mostrare immagini da un URL) e due TextViews.

Poi, dai un'occhiata a ProductCardRecyclerViewAdapter che ti abbiamo fornito. Si trova 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 riportata sopra gestisce i contenuti della nostra griglia. Per determinare cosa deve fare ogni visualizzazione con i contenuti forniti, scriveremo a breve il codice per onBindViewHolder().

Nello stesso pacchetto, puoi anche dare un'occhiata a ProductCardViewHolder. Questa classe memorizza le visualizzazioni che influiscono sul layout della carta, in modo che possiamo modificarle 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 configurare la griglia, dobbiamo prima rimuovere il segnaposto MaterialCardView da shr_product_grid_fragment.xml. Poi, devi aggiungere il componente che rappresenta la griglia di carte. In questo caso, utilizzeremo un RecyclerView. Aggiungi il componente RecyclerView a 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 file 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 RecyclerView in 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 di inizializzazione necessari per configurare un RecyclerView. Include l'impostazione del gestore del layout di RecyclerView, nonché l'inizializzazione e l'impostazione dell'adattatore di RecyclerView.

Il file ProductGridFragment.kt dovrebbe ora 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:

f9aeab846fc3bb4c.png

Ora le carte sono presenti. Non mostrano ancora nulla, quindi aggiungiamo alcuni dati di prodotto.

Aggiungi immagini e testo

Per ogni carta, aggiungi un'immagine, il nome del prodotto e il prezzo. La nostra astrazione ViewHolder contiene le visualizzazioni per ogni carta. Nel nostro ViewHolder, aggiungi le tre visualizzazioni come segue.

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 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 all'adattatore di RecyclerView cosa fare con ogni carta, utilizzando un ViewHolder.

Qui, imposta i dati di testo su ciascuno dei TextView di ViewHolder e chiama un ImageRequester per ottenere un'immagine da un URL. Il ImageRequester è una classe che abbiamo fornito per tua comodità e utilizza la libreria Volley. Questo è un argomento al di fuori dell'ambito di questo codelab, ma puoi esplorare il codice autonomamente.

Crea ed esegui:

249db074eff043f4.png

Ora i nostri prodotti vengono visualizzati nell'app.

6. Riepilogo

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 dell'app in alto con un titolo e tre pulsanti e una griglia di carte per presentare i contenuti della nostra app. La schermata Home è ora semplice e funzionale, con una struttura di base e contenuti su cui è possibile intervenire.

Passaggi successivi

Con la barra dell'app in alto, la scheda, il campo di testo e il pulsante, abbiamo utilizzato quattro componenti principali di Material Design della libreria MDC-Android. Puoi esplorare altri componenti visitando il catalogo MDC-Android.

Sebbene sia completamente funzionale, la nostra app non esprime ancora un brand o uno stile particolare. In MDC-103: temi di Material Design con colore, forma, elevazione e tipo, personalizzeremo lo stile di questi componenti per esprimere un brand vivace e moderno.

Sono riuscito a completare questo codelab con un ragionevole dispendio di tempo e impegno

Molto d'accordo D'accordo Neutro Non d'accordo Molto in disaccordo

Mi piacerebbe continuare a utilizzare i componenti Material in futuro

Molto d'accordo D'accordo Neutro Non d'accordo Molto in disaccordo