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

logo_components_color_2x_web_96dp.png

Material Components (MDC) aiuta gli sviluppatori a implementare Material Design. Creato da un team di ingegneri e progettisti UX di Google, MDC include decine di componenti UI belli e funzionali ed è disponibile 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. Ora ampliamo 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 prodotti per la casa. Contiene:

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

Componenti MDC-Android in questo codelab

  • AppBarLayout
  • MaterialCardView

Che cosa ti serve

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

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

Principiante Intermedio Avanzato

Hai seguito il corso MDC-101?

Se hai completato MDC-101, il codice dovrebbe essere pronto per questo codelab. Puoi passare al passaggio 3: Aggiungi una barra delle app nella parte superiore.

Parti da zero?

Scarica l'app codelab iniziale

Scaricare l'app iniziale

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

… oppure clonalo 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. Al termine della configurazione guidata e alla visualizzazione della finestra Benvenuto in Android Studio, fai clic su Apri un progetto Android Studio esistente. Vai alla directory in cui hai installato il codice di esempio e seleziona java -> shrine (o cerca shrine sul computer) per aprire il progetto Shrine.
  2. Attendi un attimo 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 build perché mancano l'SDK Android o gli strumenti di build, come quello mostrato di seguito. Segui le istruzioni in Android Studio per installare/aggiornare questi elementi e sincronizzare il progetto.

Aggiungere le dipendenze del progetto

Il progetto richiede una dipendenza dalla libreria di supporto MDC Android. Il codice campione che hai scaricato dovrebbe già avere questa dipendenza elencata, ma è buona norma eseguire i seguenti passaggi per assicurarsi.

  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 sincronizza 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'
}

Eseguire 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. Nella finestra Seleziona destinazione di distribuzione, se hai già un dispositivo Android elencato nei dispositivi disponibili, vai al passaggio 8. In caso contrario, fai clic su Crea nuovo dispositivo virtuale.
  4. Nella schermata Seleziona hardware, seleziona uno smartphone, ad esempio Pixel 2, e poi fai clic su Avanti.
  5. Nella schermata Immagine di sistema, seleziona una versione recente di Android, preferibilmente il livello API più alto. Se non è installato, fai clic sul link Scarica mostrato e completa il download.
  6. Fai clic su 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 Destinazione di deployment.
  9. Fai clic su Ok.
  10. Android Studio crea 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.

Ora che la schermata di accesso è a posto, inseriamo alcuni prodotti nell'app.

La schermata Home viene visualizzata quando la pagina di accesso viene chiusa, con un messaggio che dice "Hai fatto tutto!". Fantastico. Ma ora l'utente non ha azioni da intraprendere o non sa dove si trova nell'app. Per risolvere il problema, aggiungiamo la navigazione.

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

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

Aggiungere un widget AppBar

In shr_product_grid_fragment.xml, elimina il tag <LinearLayout> contenente il messaggio "Ce l'hai fatta!". TextView e sostituiscilo con quanto segue:

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

Aggiungere un'icona di navigazione

Mentre ti trovi 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 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>

Aggiungere pulsanti di azione e definire lo stile della barra delle app superiore

Puoi anche aggiungere pulsanti al lato finale della barra delle app. In Android, questi sono chiamati pulsanti di azione.

Stileremo la barra delle app superiore e aggiungeremo i pulsanti di azione al relativo menu in modo programmatico.

Innanzitutto, creiamo un metodo per configurare la barra degli strumenti. Il metodo deve ottenere un riferimento alla barra degli strumenti utilizzando id e anche un riferimento all'attività utilizzando getActivity(). Se l'attività non è nulla, imposta Toolbar da utilizzare come ActionBar utilizzando 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);
   }
}

Successivamente, direttamente sotto il metodo setUpToolbar che abbiamo appena aggiunto, eseguiamo l'override di onCreateOptionsMenu per inserire i contenuti di shr_toolbar_menu.xml nella barra degli strumenti:

ProductGridFragment.java

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
   super.onCreateOptionsMenu(menu, menuInflater);
}

Ora aggiungi una chiamata al metodo setUpToolbar che abbiamo aggiunto al contenuto del metodo onCreateView() con quanto segue:

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

Infine, aggiungi un metodo di onCreate() a ProductGridFragment.java. Nel corpo del metodo, imposta il parametro di setHasOptionMenu come true.

Il metodo dovrebbe avere questo aspetto:

ProductGridFragment.java

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setHasOptionsMenu(true);
}

Il codice precedente imposta 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 di R.menu.shr_toolbar_menu nella barra delle app.

Il file di menu contiene due elementi: "Cerca" e "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.java dovrebbe avere il seguente aspetto:

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

}

Crea ed esegui. La schermata Home dovrebbe essere simile a questa:

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 leggera, che indica che si trova su un livello diverso rispetto ai contenuti.

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

Aggiungere una carta

Iniziamo aggiungendo una scheda sotto la barra delle app in alto. Una scheda deve avere una regione per un'immagine, un titolo e un'etichetta per il testo secondario.

In shr_product_grid_fragment.xml , aggiungi quanto segue 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 notare che la scheda è rientrata dal bordo sinistro dello schermo, ha angoli arrotondati e un'ombra (che esprime l'elevazione della scheda). L'intera area è chiamata "container". A parte il contenitore stesso, 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, separatori e persino pulsanti e icone. Ad esempio, la scheda che abbiamo appena creato contiene due TextView (uno per il titolo e uno per il testo secondario) in un LinearLayout, allineati alla parte inferiore della scheda.

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

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

Configurare la griglia di 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>

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

Dopodiché, dai un'occhiata ai ProductCardRecyclerViewAdapter che abbiamo fornito. Si trova nello stesso pacchetto di 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();
   }
}

La classe adattatore riportata sopra gestisce i contenuti della nostra griglia. Per determinare cosa deve fare ogni visualizzazione con i contenuti forniti, a breve scriveremo il codice per onBindViewHolder().

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

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

Per configurare la griglia, dobbiamo prima rimuovere il segnaposto MaterialCardView da shr_product_grid_fragment.xml. A questo punto, aggiungi il componente che rappresenta la griglia di schede. In questo caso, aggiungi un componente RecyclerView al tuo 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 in ProductGridFragment.java dopo aver chiamato setUpToolbar(view) e prima dell'istruzione 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;
}

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

Il file ProductGridFragment.java ora dovrebbe avere il seguente aspetto:

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

}

Crea ed esegui.

Ora le schede sono disponibili. 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 il prezzo. La nostra astrazione ViewHolder contiene le visualizzazioni per ogni scheda. Nel nostro ViewHolder, aggiungi le tre visualizzazioni come segue:

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

Nell'adattatore di RecyclerView, nell'ViewHolder, aggiorna il metodo onBindViewHolder() per impostare le informazioni su ogni visualizzazione:

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

Il codice riportato sopra indica all'adattatore di RecyclerView cosa fare con ogni scheda, utilizzando un ViewHolder.

Qui imposta i dati di testo su ciascun ViewHolder TextView e chiama un ImageRequester per ottenere un'immagine da un URL. ImageRequester è una classe che abbiamo fornito per comodità e utilizza la libreria Volley (questo argomento non rientra nell'ambito di questo codelab, ma puoi esplorare il codice in autonomia).

Crea ed esegui:

Ora 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. Con poche righe di codice, abbiamo aggiunto una barra dell'app superiore con un titolo e tre pulsanti, nonché una griglia di schede per presentare i contenuti della nostra app. La nostra schermata Home è ora semplice e funzionale, con una struttura di base e contenuti su cui è possibile intervenire.

Passaggi successivi

Con la barra delle app superiore, la scheda, il campo di testo e il pulsante, ora abbiamo utilizzato quattro componenti principali di Material Design della libreria MDC-Android. Puoi esplorare altri componenti nel catalogo componenti MDC-Android.

Sebbene sia completamente funzionale, la nostra app non esprime ancora un brand particolare. In MDC-103: Material Design Theming with Color, Shape, Elevation and Type, 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

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

Vorrei continuare a utilizzare i componenti Material in futuro

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