MDC-102 Android: Material Structure and Layout (Kotlin)

1. Einführung

logo_components_color_2x_web_96dp.png

Mit Material Components (MDC) können Entwickler Material Design implementieren. MDC wurde von einem Team von Entwicklern und UX-Designern bei Google entwickelt und bietet Dutzende ansprechender und funktionaler UI-Komponenten. Es ist für Android, iOS, Web und Flutter verfügbar.material.io/develop

Im Codelab MDC-101 haben Sie zwei Material Components (MDC) verwendet, um eine Anmeldeseite zu erstellen: Textfelder und Schaltflächen mit Tintenwellen. Erweitern wir nun diese Grundlage, indem wir Navigation, Struktur und Daten hinzufügen.

Umfang

In diesem Codelab erstellen Sie einen Startbildschirm für eine App namens Shrine, eine E-Commerce-App für Kleidung und Haushaltswaren. Sie enthält:

  • Eine obere App-Leiste
  • Eine Rasterliste mit Produkten

249db074eff043f4.png

Codelab: MC-Android-Komponenten

  • AppBarLayout
  • MaterialCardView

Voraussetzungen

  • Grundkenntnisse in der Android-Entwicklung
  • Android Studio (hier herunterladen, falls Sie es noch nicht haben)
  • Einen Android-Emulator oder ein Android-Gerät (über Android Studio verfügbar)
  • Beispielcode (siehe nächster Schritt)

Wie würdest du deine Erfahrung mit der Entwicklung von Android-Apps bewerten?

Neuling Mittel Kompetent

2. Entwicklungsumgebung einrichten

Weiter von MDC-101?

Wenn du MDC-101 abgeschlossen hast, sollte dein Code für dieses Codelab vorbereitet sein. Fahren Sie mit Schritt 3 fort: Obere App-Leiste hinzufügen.

Neu beginnen?

Codelab-App für den Einstieg herunterladen

Die Starter-App befindet sich im Verzeichnis material-components-android-codelabs-102-starter/kotlin. Sie müssen sich vor Beginn in diesem Verzeichnis cd befinden.

…oder es aus GitHub klonen

Führen Sie die folgenden Befehle aus, um dieses Codelab von GitHub zu klonen:

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

Startcode in Android Studio laden

  1. Wenn der Einrichtungsassistent abgeschlossen ist und das Fenster Willkommen bei Android Studio angezeigt wird, klicken Sie auf Bestehendes Android Studio-Projekt öffnen. Gehen Sie zu dem Verzeichnis, in dem Sie den Beispielcode installiert haben, und wählen Sie kötlin -> Schrein aus oder suchen Sie auf Ihrem Computer nach shrine, um das Versandprojekt zu öffnen.
  2. Warten Sie einen Moment, bis das Projekt in Android Studio erstellt und synchronisiert wurde. Dies können Sie an den Aktivitätsanzeigen unten im Android Studio-Fenster erkennen.
  3. An dieser Stelle meldet Android Studio möglicherweise einige Buildfehler, weil das Android SDK oder die Buildtools fehlen, z. B. den unten gezeigten. Folgen Sie der Anleitung in Android Studio, um diese zu installieren/aktualisieren und Ihr Projekt zu synchronisieren.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

Projektabhängigkeiten hinzufügen

Für das Projekt ist eine Abhängigkeit von der MDC-Android-Supportbibliothek erforderlich. Im Beispielcode, den Sie heruntergeladen haben, sollte diese Abhängigkeit bereits aufgeführt sein. Es empfiehlt sich jedoch, die folgenden Schritte durchzuführen, um sicherzugehen.

  1. Rufen Sie die build.gradle-Datei des app-Moduls auf und prüfen Sie, ob der dependencies-Block eine Abhängigkeit von MDC Android enthält:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. Optional: Bearbeiten Sie bei Bedarf die Datei build.gradle, um die folgenden Abhängigkeiten hinzuzufügen, und synchronisieren Sie das Projekt.
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'
}

Starter-App ausführen

  1. Die Build-Konfiguration links neben der Schaltfläche Ausführen/Wiedergeben muss app sein.
  2. Klicken Sie auf die grüne Schaltfläche Run / Play, um die App zu erstellen und auszuführen.
  3. Wenn im Fenster Select Deployment Target (Bereitstellungsziel auswählen) unter den verfügbaren Geräten bereits ein Android-Gerät aufgeführt ist, fahren Sie mit Schritt 8 fort. Klicken Sie andernfalls auf Neues virtuelles Gerät erstellen.
  4. Wählen Sie auf dem Bildschirm Hardware auswählen ein Smartphone wie Pixel 2 aus und klicken Sie auf Weiter.
  5. Wählen Sie auf dem Bildschirm System-Image die aktuelle Android-Version aus, vorzugsweise die höchste API-Ebene. Wenn die App nicht installiert ist, klicken Sie auf den angezeigten Link Herunterladen und führen Sie den Download aus.
  6. Klicken Sie auf Weiter.
  7. Lassen Sie auf dem Bildschirm Android Virtual Device (AVD) die Einstellungen unverändert und klicken Sie auf Fertigstellen.
  8. Wählen Sie im Dialogfeld „Bereitstellungsziel“ ein Android-Gerät aus.
  9. Klicken Sie auf OK.
  10. Android Studio erstellt die App, stellt sie bereit und öffnet sie automatisch auf dem Zielgerät.

Fertig! Sie sollten die Anmeldeseite von Shrine aus dem MDC-101-Codelab sehen.

4cb0c218948144b4.png

Jetzt, da der Anmeldebildschirm gut aussieht, fügen wir einige Produkte in die App ein.

3. App-Leiste oben hinzufügen

Wenn die Anmeldeseite geschlossen wird, wird der Startbildschirm mit der Meldung „Du hast es geschafft!“ angezeigt. Sehr gut. Jetzt kann der Nutzer aber nichts tun und hat keine Ahnung, wo er sich in der App befindet. Um das zu ändern, fügen wir eine Navigation hinzu.

Material Design bietet Navigationsmuster, die für eine hohe Nutzerfreundlichkeit sorgen. Eine der sichtbarsten Komponenten ist die obere App-Leiste.

Fügen Sie eine obere App-Leiste hinzu, um die Navigation zu ermöglichen und Nutzern schnellen Zugriff auf andere Aktionen zu ermöglichen.

AppBar-Widget hinzufügen

Löschen Sie in shr_product_grid_fragment.xml den Block <LinearLayout> mit dem Text „Du hast es geschafft!“. TextView und ersetzen Sie ihn durch Folgendes:

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>

Ihr shr_product_grid_fragment.xml sollte jetzt so aussehen:

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>

Viele App-Leisten haben neben dem Titel eine Schaltfläche. Fügen wir unserem ein Menüsymbol hinzu.

Navigationssymbol hinzufügen

Bleiben Sie im shr_product_grid_fragment.xml und fügen Sie der XML-Komponente Toolbar, die Sie gerade zu Ihrem Layout hinzugefügt haben, Folgendes hinzu:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

Ihre shr_product_grid_fragment.xml sollte so aussehen:

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>

Aktionsschaltflächen hinzufügen und die obere App-Leiste stylen

Sie können auch am Ende der App-Leiste Schaltflächen hinzufügen. Unter Android werden diese als Aktionsschaltflächen bezeichnet. Wir gestalten die obere App-Leiste und fügen dem Menü programmatisch Aktionsschaltflächen hinzu.

Legen Sie in der Funktion onCreateView von ProductGridFragment.kt mithilfe von setSupportActionBar die Toolbar der activity fest, die als ActionBar verwendet werden soll. Sie können dies nach dem Erstellen der Ansicht mit der inflater tun.

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

Als Nächstes überschreiben wir direkt unter der Methode, die wir gerade zum Einrichten der Symbolleiste geändert haben, onCreateOptionsMenu, um den Inhalt von shr_toolbar_menu.xml in der Symbolleiste zu maximieren:

ProductGridFragment.kt

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

Überschreiben Sie schließlich onCreate() in ProductGridFragment.kt und rufen Sie nach dem Aufrufen von super() setHasOptionMenu mit true auf:

ProductGridFragment.kt

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

Durch die obigen Code-Snippets wird die App-Leiste aus unserem XML-Layout zur Aktionsleiste für diese Aktivität. Der Rückruf onCreateOptionsMenu gibt der Aktivität an, was als Menü verwendet werden soll. In diesem Fall werden die Menüpunkte von R.menu.shr_toolbar_menu in der App-Leiste platziert. Die Menüdatei enthält zwei Elemente: „Suchen“ und „Filtern“.

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>

Nach diesen Änderungen sollte Ihre ProductGridFragment.kt-Datei so aussehen:

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

Erstellen und ausführen. Ihr Startbildschirm sollte nun so aussehen:

d04e8aa3b27f4754.png

Die Symbolleiste enthält jetzt auf der rechten Seite ein Navigationssymbol, einen Titel und zwei Aktionssymbole. Die Symbolleiste zeigt auch Höhendaten mithilfe eines dezenten Schattens an, der darauf hinweist, dass sich die Ebene auf einer anderen Ebene als der Inhalt befindet.

4. Karte hinzufügen

Jetzt, da unsere App eine gewisse Struktur hat, können wir die Inhalte organisieren, indem wir sie auf Karten platzieren.

Karte hinzufügen

Fügen Sie zuerst eine Karte unter der oberen App-Leiste hinzu. Eine Karte sollte einen Bereich für ein Bild, einen Titel und ein Label für sekundären Text haben. Fügen Sie Folgendes in shr_product_grid_fragment.xml unter AppBarLayout hinzu.

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>

Erstellen und ausführen:

f6184a55ccb5f920.png

In dieser Vorschau sehen Sie, dass die Karte vom linken Rand aus platziert ist und abgerundete Ecken und einen Schatten hat, der die Höhe der Karte zum Ausdruck bringt. Das gesamte Element wird als „Container“ bezeichnet. Abgesehen vom Container sind alle darin enthaltenen Elemente optional.

Sie können einem Container die folgenden Elemente hinzufügen: Text für die Überschrift, ein Thumbnail oder Avatar, Text für Zwischenüberschriften, Trennlinien und sogar Schaltflächen und Symbole. Die Karte, die wir gerade erstellt haben, enthält beispielsweise zwei TextViews (eine für den Titel und eine für sekundären Text) in einem LinearLayout, die unten auf der Karte ausgerichtet sind.

Karten werden normalerweise in einer Sammlung mit anderen Karten angezeigt. Im nächsten Abschnitt dieses Codelabs legen wir sie als Sammlung in einem Raster dar.

5. Kartenraster erstellen

Wenn auf einem Bildschirm mehrere Karten angezeigt werden, werden sie in einer oder mehreren Sammlungen gruppiert. Karten in einem Raster liegen in einer Ebene, d. h., sie haben dieselbe Ruhehöhe wie die anderen Karten (es sei denn, sie werden aufgehoben oder verschoben, was in diesem Codelab jedoch nicht behandelt wird).

Kartenraster einrichten

Sehen Sie sich die Datei shr_product_card.xml an, die wir für Sie bereitgestellt haben:

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>

Dieses Kartenlayout enthält eine Karte mit einem Bild (in diesem Fall ein NetworkImageView, mit dem Bilder über eine URL geladen und angezeigt werden können) und zwei TextViews.

Sehen Sie sich als Nächstes die von uns bereitgestellte ProductCardRecyclerViewAdapter an. Sie befindet sich im selben Paket wie 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
   }
}

Die Adapterklasse oben verwaltet die Inhalte unseres Rasters. Um festzulegen, was jede Ansicht mit den jeweiligen Inhalten tun soll, schreiben wir demnächst den Code für onBindViewHolder().

Im selben Paket finden Sie auch ProductCardViewHolder. In dieser Klasse werden die Ansichten gespeichert, die sich auf das Kartenlayout auswirken, damit wir sie später ändern können.

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)

Zum Einrichten des Rasters entfernen wir zuerst den Platzhalter MaterialCardView aus shr_product_grid_fragment.xml. Als Nächstes fügen Sie die Komponente hinzu, die das Kartenraster darstellt. In diesem Fall verwenden wir RecyclerView. Fügen Sie die RecyclerView-Komponente unter der XML-Komponente AppBarLayout zu shr_product_grid_fragment.xml hinzu:

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>

Ihre shr_product_grid_fragment.xml sollte so aussehen:

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>

Fügen Sie in onCreateView() den RecyclerView-Initialisierungscode in ProductGridFragment.kt ein, nachdem Sie setUpToolbar(view) aufgerufen und vor der return-Anweisung platziert haben:

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

Das obige Code-Snippet enthält die erforderlichen Initialisierungsschritte zum Einrichten von RecyclerView. Dazu gehören das Festlegen des Layoutmanagers von RecyclerView sowie das Initialisieren und Festlegen des Adapters von RecyclerView.

Die Datei ProductGridFragment.kt sollte jetzt so aussehen:

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

Erstellen und ausführen:

f9aeab846fc3bb4c.png

Die Karten sind da! Es werden noch nichts angezeigt, also lassen Sie uns einige Produktdaten hinzufügen.

Bilder und Text hinzufügen

Fügen Sie für jede Karte ein Bild, einen Produktnamen und einen Preis hinzu. Die ViewHolder-Abstraktion enthält die Aufrufe für jede Karte. Fügen Sie die drei Ansichten in der ViewHolder so hinzu:

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

Aktualisieren Sie die onBindViewHolder()-Methode im ProductCardRecyclerViewAdapter, um den Titel, den Preis und das Produktbild für jede Produktansicht festzulegen, wie unten dargestellt:

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

Im obigen Code wird dem Adapter unserer RecyclerView mithilfe einer ViewHolder mitgeteilt, was mit jeder Karte zu tun ist.

Hier werden die Textdaten für alle TextViews der ViewHolder festgelegt und eine ImageRequester aufgerufen, um ein Bild von einer URL abzurufen. Die ImageRequester ist eine Klasse, die wir für Sie bereitgestellt haben. Sie verwendet die Volley-Bibliothek. Dieses Thema fällt nicht in den Rahmen dieses Codelabs, aber Sie können sich den Code gern selbst ansehen.

Erstellen Sie den folgenden Befehl und führen Sie ihn aus:

249db074eff043f4.png

Unsere Produkte werden jetzt in der App angezeigt.

6. Zusammenfassung

Unsere App hat einen grundlegenden Ablauf, der den Nutzer vom Anmeldebildschirm zu einem Startbildschirm bringt, auf dem die Produkte angezeigt werden können. Mit nur wenigen Codezeilen haben wir eine obere App-Leiste mit einem Titel und drei Schaltflächen sowie ein Kartenraster hinzugefügt, um die Inhalte unserer App zu präsentieren. Der Startbildschirm ist jetzt einfach und funktional, mit einer einfachen Struktur und umsetzbaren Inhalten.

Weiteres Vorgehen

Mit der oberen App-Leiste, der Karte, dem Textfeld und der Schaltfläche haben wir nun vier Kernkomponenten von Material Design aus der MDC-Android-Bibliothek verwendet. Weitere Komponenten finden Sie im MDC-Android-Katalog.

Sie ist zwar voll funktionsfähig, aber unsere App drückt noch keine bestimmte Marke oder keinen bestimmten Stil aus. In MDC-103: Material Design Theming with Color, Shape, Elevation and Type passen wir den Stil dieser Komponenten an, um eine lebendige, moderne Marke auszudrücken.

Ich konnte dieses Codelab mit angemessenem Zeit- und Arbeitsaufwand abschließen

Stimme vollkommen zu Stimme zu Neutral Stimme nicht zu Stimme überhaupt nicht zu

Ich möchte Material Components weiterhin verwenden.

Stimme vollkommen zu Stimme zu Neutral Stimme nicht zu Stimme überhaupt nicht zu