MDC-101 Android: Material Components (MDC) Basics (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 aus Entwicklern und UX-Designern bei Google entwickelt. Es enthält Dutzende schöne und funktionale UI-Komponenten und ist für Android, iOS, das Web und Flutter.material.io/develop verfügbar.

Was sind Material Design und Material Components für Android?

Material Design ist ein System zum Erstellen ausdrucksstarker und ansprechender digitaler Produkte. Wenn Produktteams Stil, Branding, Interaktion und Bewegung in einer einheitlichen Reihe von Prinzipien und Komponenten vereinen, können sie ihr volles Designpotenzial ausschöpfen.

Bei Android-Apps vereint Material Components for Android (MDC Android) Design und Entwicklung mit einer Bibliothek von Komponenten, um für Konsistenz in Ihrer App zu sorgen. Im Zuge der Weiterentwicklung des Material Design-Systems werden diese Komponenten aktualisiert, um eine konsistente Pixel-perfekte Implementierung und die Einhaltung der Google-Frontend-Entwicklungsstandards zu gewährleisten. MDC ist auch für das Web, iOS und Flutter verfügbar.

In diesem Codelab erstellen Sie eine Anmeldeseite mit mehreren Komponenten von MDC Android.

Inhalt

Dieses Codelab ist das erste von vier Codelabs, in denen Sie die App Shrine erstellen. Das ist eine E-Commerce-Android-App, in der Kleidung und Haushaltswaren verkauft werden. Es wird gezeigt, wie Sie mithilfe von MDC Android Komponenten an jede Marke oder jeden Stil anpassen können.

In diesem Codelab erstellen Sie eine Anmeldeseite für Shrine mit folgenden Elementen:

  • Zwei Textfelder, eines zum Eingeben eines Nutzernamens und eines für ein Passwort
  • Zwei Schaltflächen, eine für „Abbrechen“ und eine für „Weiter“
  • Der Name der App (Schrein)
  • Bild des Shrine-Logos

4cb0c218948144b4.png

MDC-Android-Komponenten in diesem Codelab

  • Textfeld
  • Schaltfläche

Voraussetzungen

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

Wie würden Sie Ihre Erfahrung im Erstellen von Android-Apps bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Entwicklungsumgebung einrichten

Android Studio starten

Wenn Sie Android Studio öffnen, sollte ein Fenster mit dem Titel „Welcome to Android Studio“ (Willkommen bei Android Studio) angezeigt werden. Wenn Sie Android Studio jedoch zum ersten Mal starten, führen Sie die Schritte im Android Studio-Einrichtungsassistenten mit den Standardwerten aus. Das Herunterladen und Installieren der erforderlichen Dateien kann einige Minuten dauern. Sie können diesen Vorgang im Hintergrund laufen lassen, während Sie mit dem nächsten Abschnitt fortfahren.

Starter-Codelab-App herunterladen

Die Starter-App befindet sich im Verzeichnis material-components-android-codelabs-101-starter/kotlin.

...oder von 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 101-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. Rufen Sie das Verzeichnis auf, in dem Sie den Beispielcode installiert haben, und wählen Sie kotlin -> shrine aus oder suchen Sie auf Ihrem Computer nach shrine, um das Shipping-Projekt 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 bzw. zu 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 eine neuere Android-Version aus, vorzugsweise die höchste API-Ebene. Falls sie nicht installiert ist, klicken Sie auf den angezeigten Link Herunterladen und schließen Sie den Download ab.
  6. Klicken Sie auf Weiter.
  7. Lassen Sie die Einstellungen auf dem Bildschirm Android Virtual Device (AVD) unverändert und klicken Sie auf Finish (Fertigstellen).
  8. Wählen Sie im Dialogfeld für das 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! Der Startcode für die Anmeldeseite von Shrine sollte in deinem Emulator ausgeführt werden. Der Name „Schrein“ und das Logo des Schreins direkt darunter sind zu sehen.

e7ed014e84755811.png

Sehen wir uns den Code an. In unserem Beispielcode finden Sie ein einfaches Fragment-Navigations-Framework, mit dem Sie Fragmente anzeigen und zwischen Fragmenten wechseln können.

Öffnen Sie MainActivity.kt im Verzeichnis shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine. Sie sollte Folgendes enthalten:

MainActivity.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment

class MainActivity : AppCompatActivity(), NavigationHost {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.shr_main_activity)

       if (savedInstanceState == null) {
           supportFragmentManager
                   .beginTransaction()
                   .add(R.id.container, LoginFragment())
                   .commit()
       }
   }

   override fun navigateTo(fragment: Fragment, addToBackstack: Boolean) {
       val transaction = supportFragmentManager
               .beginTransaction()
               .replace(R.id.container, fragment)

       if (addToBackstack) {
           transaction.addToBackStack(null)
       }

       transaction.commit()
   }
}

Bei dieser Aktivität wird die in shr_main_activity.xml definierte Layoutdatei R.layout.shr_main_activity angezeigt.

Wie Sie sehen, startet MainActivity.kt in onCreate(), eine Fragment-Transaktion, um LoginFragment anzuzeigen. In diesem Codelab ändern wir LoginFragment. Die Aktivität implementiert auch eine navigateTo(Fragment)-Methode, die in NavigationHost definiert ist und mit der jedes Fragment zu einem anderen Fragment wechseln kann.

Klicken Sie in der Aktivitätsdatei mit Befehlstaste + Klicken (oder Strg + Klicken) auf shr_main_activity, um die Layoutdatei zu öffnen, oder rufen Sie die Layoutdatei in app -> res -> layout -> shr_main_activity.xml auf.

shr_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity"/>

Hier sehen wir ein einfaches <FrameLayout>, das als Container für alle Fragmente dient, die in der Aktivität angezeigt werden.

Als Nächstes öffnen wir LoginFragment.kt.

LoginFragment.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class LoginFragment : Fragment() {

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       return view
   }
}

LoginFragment bläst die Layoutdatei shr_login_fragment auf und zeigt sie in onCreateView() an.

Sehen wir uns nun die Layoutdatei shr_login_fragment.xml an, um zu sehen, wie die Anmeldeseite aussieht.

shr_login_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
   android:background="@color/loginPageBackgroundColor"
   tools:context=".LoginFragment">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:clipChildren="false"
       android:clipToPadding="false"
       android:orientation="vertical"
       android:padding="24dp"
       android:paddingTop="16dp">

       <ImageView
           android:layout_width="64dp"
           android:layout_height="64dp"
           android:layout_gravity="center_horizontal"
           android:layout_marginTop="48dp"
           android:layout_marginBottom="16dp"
           app:srcCompat="@drawable/shr_logo" />

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:layout_marginBottom="132dp"
           android:text="@string/shr_app_name"
           android:textAllCaps="true"
           android:textSize="16sp" />
   </LinearLayout>
</ScrollView>

Hier sehen Sie ein <LinearLayout> mit einem <ImageView> oben, das für das Logo des Schreins steht.

Darauf folgt ein <TextView>-Tag, das für das Schrein-Label unter dem Logo steht. Der Text für dieses Label ist eine Stringressource mit dem Namen @string/shr_app_name. Wenn Sie auf den Namen der Stringressource Befehlstaste + Klicken (oder Strg + Klicken) oder app -> res -> values -> strings.xml öffnen, wird die Datei strings.xml angezeigt, in der Stringressourcen definiert sind. Wenn in Zukunft weitere Stringressourcen hinzugefügt werden, werden sie hier definiert. Jede Ressource in dieser Datei sollte das Präfix shr_ haben, um anzugeben, dass sie Teil der Shrine-App ist.

Nachdem Sie sich mit dem Startcode vertraut gemacht haben, implementieren wir nun unsere erste Komponente.

3. Textfelder hinzufügen

Zunächst fügen wir zwei Textfelder zu unserer Anmeldeseite hinzu, in die Nutzer ihren Nutzernamen und ihr Passwort eingeben können. Wir verwenden die MDC-Textfeldkomponente, die integrierte Funktionen enthält, mit denen ein schwebendes Label und Fehlermeldungen angezeigt werden.

d83c47fb4aed3a82.png

XML hinzufügen

Fügen Sie in shr_login_fragment.xml zwei TextInputLayout-Elemente mit einem untergeordneten TextInputEditText-Element in <LinearLayout> unter dem Label „SHRINE“ <TextView> hinzu:

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

Das obige Snippet stellt zwei Textfelder dar, die jeweils aus einem <TextInputLayout>-Element und einem untergeordneten <TextInputEditText>-Element bestehen. Der Hinweistext für jedes Textfeld wird im Attribut android:hint angegeben.

Wir haben zwei neue Stringressourcen für das Textfeld hinzugefügt: @string/shr_hint_username und @string/shr_hint_password. Öffnen Sie strings.xml, um diese Stringressourcen zu sehen.

strings.xml

<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>

Eingabevalidierung hinzufügen

TextInputLayout-Komponenten bieten eine integrierte Fehlerfeedbackfunktion.

Nehmen Sie folgende Änderungen an shr_login_fragment.xml vor, damit Fehlerfeedback angezeigt werden kann:

  • Legen Sie das Attribut app:errorEnabled für das Element PasswortTextInputLayout auf true fest. Dadurch wird die Fehlermeldung unterhalb des Textfeldes um einen zusätzlichen Abstand ergänzt.
  • Legen Sie für das Element PasswortTextInputEditText das Attribut android:inputType auf textPassword fest. Dadurch wird der Eingabetext im Passwortfeld ausgeblendet.

Nach dieser Änderung sollten die Textfelder in shr_login_fragment.xml so aussehen:

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password"
   app:errorEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>

Versuchen Sie nun, die App auszuführen. Es sollte eine Seite mit zwei Textfeldern für „Nutzername“ und „Passwort“ angezeigt werden.

Hier sehen Sie eine Animation des schwebenden Labels:

333184b615aed4f7.gif

4. Schaltflächen hinzufügen

Als Nächstes fügen wir unserer Anmeldeseite zwei Schaltflächen hinzu: „Abbrechen“ und „Weiter“. Wir verwenden die MDC-Schaltflächenkomponente, die den ikonischen Material Design-Ripple-Effekt enthält.

4cb0c218948144b4.png

XML hinzufügen

Füge in shr_login_fragment.xml dem <LinearLayout> unter den TextInputLayout-Elementen ein <RelativeLayout> hinzu. Fügen Sie dann zwei <MaterialButton>-Elemente zu <RelativeLayout> hinzu.

Die resultierende XML-Datei sollte so aussehen:

shr_login_fragment.xml

<RelativeLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <com.google.android.material.button.MaterialButton
       android:id="@+id/next_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentEnd="true"
       android:layout_alignParentRight="true"
       android:text="@string/shr_button_next" />

   <com.google.android.material.button.MaterialButton
       android:id="@+id/cancel_button"
       style="@style/Widget.MaterialComponents.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="12dp"
       android:layout_marginRight="12dp"
       android:layout_toStartOf="@id/next_button"
       android:layout_toLeftOf="@id/next_button"
       android:text="@string/shr_button_cancel" />

</RelativeLayout>

Fertig! Wenn Sie die App ausführen, wird beim Tippen auf die einzelnen Schaltflächen eine Tintenwelle angezeigt.

9dd162d65e4a92a2.gif

5. Zum nächsten Fragment gehen

Zum Schluss fügen wir LoginFragment.kt etwas Kotlin-Code hinzu, um die Schaltfläche „WEITER“ mit dem Übergang zu einem anderen Fragment zu verknüpfen.

Fügen wir in LoginFragment.kt unterhalb von onCreateView() eine private boolesche isPasswordValid-Methode mit Logik hinzu, die bestimmt, ob das Passwort gültig ist oder nicht. Für diese Demo achten wir nur darauf, dass das Passwort mindestens acht Zeichen lang ist:

LoginFragment.kt

private fun isPasswordValid(text: Editable?): Boolean {
   return text != null && text.length >= 8
}

Fügen Sie als Nächstes der Schaltfläche „Weiter“ einen Klick-Listener hinzu, der den Fehler basierend auf der gerade erstellten isPasswordValid()-Methode festlegt und löscht. In onCreateView() sollte dieser Klick-Listener zwischen der Inflater-Zeile und der return view-Zeile platziert werden.

Fügen wir dem Passwort TextInputEditText nun einen Schlüssel-Listener hinzu, der auf Schlüsselereignisse wartet, die den Fehler beheben würden. Dieser Listener sollte auch isPasswordValid() verwenden, um zu prüfen, ob das Passwort gültig ist. Sie können sie direkt unter dem Klick-Listener in onCreateView() hinzufügen.

Die onCreateView()-Methode sollte nun in etwa so aussehen:

LoginFragment.kt

override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment.
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       // Set an error if the password is less than 8 characters.
       view.next_button.setOnClickListener({
           if (!isPasswordValid(password_edit_text.text!!)) {
               password_text_input.error = getString(R.string.shr_error_password)
           } else {
               // Clear the error.
               password_text_input.error = null
           }
       })

       // Clear the error once more than 8 characters are typed.
       view.password_edit_text.setOnKeyListener({ _, _, _ ->
           if (isPasswordValid(password_edit_text.text!!)) {
               // Clear the error.
               password_text_input.error = null
           }
           false
       })

       return view
   }
}

Jetzt können wir zu einem anderen Fragment navigieren. Aktualisieren Sie in onCreateView() die OnClickListener, um zu einem anderen Fragment zu wechseln, wenn die Fehlerprüfung erfolgreich war. Ihr clickListener-Code sollte jetzt so aussehen:

LoginFragment.kt

// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
   if (!isPasswordValid(password_edit_text.text!!)) {
       password_text_input.error = getString(R.string.shr_error_password)
   } else {
       // Clear the error.
       password_text_input.error = null
       // Navigate to the next Fragment.
       (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
   }
})

Wir haben der else-Kasus des Klick-Listeners die Zeile (activity as NavigationHost).navigateTo(ProductGridFragment(), false) hinzugefügt. In dieser Zeile wird die Methode navigateTo() von MainActivity aufgerufen, um zu einem neuen Fragment zu gelangen: ProductGridFragment. Derzeit ist dies eine leere Seite, an der Sie in MDC-102 arbeiten werden.

Erstellen Sie nun die App. Klicken Sie auf die Schaltfläche „Weiter“.

Geschafft! Dieser Bildschirm ist der Ausgangspunkt für unser nächstes Codelab, an dem Sie in MDC-102 arbeiten werden.

6. Fertig

Mithilfe von einfachem XML-Markup und etwa 30 Zeilen Kotlin haben Sie mit der Material Components for Android-Bibliothek eine ansprechende Anmeldeseite erstellt, die den Material Design-Richtlinien entspricht und auf allen Geräten einheitlich aussieht und funktioniert.

Weiteres Vorgehen

Das Textfeld und die Schaltfläche sind zwei Hauptkomponenten der MDC-Android-Bibliothek, es gibt aber noch viele weitere. Sie können sich auch die übrigen Komponenten für MDC Android ansehen. Alternativ können Sie sich MDC 102: Material Design Structure and Layout ansehen, um mehr über die obere App-Leiste, die Kartenansicht und das Rasterlayout zu erfahren. Vielen Dank, dass Sie Material Components ausprobieren. Wir hoffen, dieses Codelab hat Ihnen gefallen.

Ich konnte dieses Codelab mit angemessenem Zeitaufwand und Mühe abschließen.

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

Ich möchte Material Components weiterhin verwenden.

Stimme voll und ganz zu Stimme zu Neutral Stimme nicht zu Stimme überhaupt nicht zu