Material Components (MDC) helfen Entwicklern bei der Implementierung von Material Design. MDC wurde von einem Team aus Entwicklern und UX-Designern bei Google entwickelt und bietet Dutzende von ansprechenden und funktionalen UI-Komponenten. Es ist für Android, iOS, Web und Flutter verfügbar. material.io/develop |
Was sind Material Design und Material-Komponenten für Android?
Material Design ist ein System zum Erstellen ansprechender digitaler Produkte. Wenn Stil, Branding, Interaktion und Bewegung unter einer einheitlichen Reihe von Prinzipien und Komponenten vereint werden, können Produktteams ihr größtes Designpotenzial entfalten.
Für Android-Anwendungen vereint Material Components for Android(MDC Android) Design und Entwicklung mit einer Bibliothek von Komponenten, mit denen Sie für Konsistenz in Ihrer Anwendung sorgen können. Im Zuge der Weiterentwicklung des Material Design-Systems werden diese Komponenten aktualisiert, um eine konsistente, pixelgenaue Implementierung und die Einhaltung der Google-Standards für die Frontend-Entwicklung zu gewährleisten. MDC ist auch für Web, iOS und Flutter verfügbar.
In diesem Codelab erstellen Sie eine Anmeldeseite mit mehreren Komponenten von MDC Android.
Umfang
Dieses Codelab ist das erste von vier Codelabs, in denen Sie eine App namens Shrine erstellen. Das ist eine E-Commerce-Android-App, in der Kleidung und Haushaltswaren verkauft werden. Darin wird gezeigt, wie Sie Komponenten mit MDC-Android an eine Marke oder einen Stil anpassen können.
In diesem Codelab erstellen Sie eine Anmeldeseite für Shrine, die Folgendes enthält:
- Zwei Textfelder, eines für die Eingabe eines Nutzernamens und das andere für ein Passwort
- Zwei Schaltflächen: „Abbrechen“ und „Weiter“
- Der Name der App (Shrine)
- Ein Bild des Shrine-Logos
MDC Android-Komponenten in diesem Codelab
- Textfeld
- Schaltfläche
Voraussetzungen
- Grundkenntnisse in der Android-Entwicklung
- Android Studio (hier herunterladen, falls noch nicht vorhanden)
- Ein Android-Emulator oder -Gerät (über Android Studio verfügbar)
- Der Beispielcode (siehe nächsten Schritt)
Wie würden Sie Ihre Erfahrung bei der Entwicklung von Android-Apps bewerten?
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 des Android Studio-Einrichtungsassistenten mit den Standardwerten aus. Das Herunterladen und Installieren der erforderlichen Dateien kann einige Minuten dauern. Sie können diesen Schritt also im Hintergrund ausführen, während Sie mit dem nächsten Abschnitt fortfahren.
Starter-App für das Codelab herunterladen
Die Starter-App befindet sich im Verzeichnis material-components-android-codelabs-101-starter/java
.
…oder 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 101-starter
Startcode in Android Studio laden
- Wenn der Einrichtungsassistent abgeschlossen ist und das Fenster Welcome to Android Studio angezeigt wird, klicken Sie auf Open an existing Android Studio project. Rufen Sie das Verzeichnis auf, in dem Sie den Beispielcode installiert haben, und wählen Sie java -> shrine aus(oder suchen Sie auf Ihrem Computer nach shrine), um das Shrine-Projekt zu öffnen.
- Warten Sie einen Moment, bis Android Studio das Projekt erstellt und synchronisiert hat. Die Aktivitätsanzeigen unten im Android Studio-Fenster geben Aufschluss über den Fortschritt.
- An diesem Punkt werden in Android Studio möglicherweise einige Build-Fehler angezeigt, weil das Android SDK oder Build-Tools wie das unten gezeigte fehlen. Folgen Sie der Anleitung in Android Studio, um diese zu installieren/aktualisieren und Ihr Projekt zu synchronisieren.
Projektabhängigkeiten hinzufügen
Das Projekt benötigt eine Abhängigkeit von der MDC Android Support Library. Die heruntergeladenen Beispielcodes sollten diese Abhängigkeit bereits enthalten. Es empfiehlt sich jedoch, die folgenden Schritte auszuführen, um sicherzugehen.
- Rufen Sie die Datei
build.gradle
des Modulsapp
auf und prüfen Sie, ob der Blockdependencies
eine Abhängigkeit von MDC Android enthält:
api 'com.google.android.material:material:1.1.0-alpha06'
- 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' }
Start-App ausführen
|
Fertig! Der Startcode für die Anmeldeseite von Shrine sollte in Ihrem Emulator ausgeführt werden. Sie sollten den Namen „Shrine“ und das Shrine-Logo direkt darunter sehen.
Sehen wir uns den Code an. In unserem Beispielcode haben wir ein einfaches Fragment
-Navigationsframework bereitgestellt, mit dem Fragmente angezeigt und zwischen Fragmenten gewechselt werden kann.
Öffnen Sie MainActivity.java
im Verzeichnis shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.java.shrine
. Sie sollte Folgendes enthalten:
MainActivity.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements NavigationHost {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shr_main_activity);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new LoginFragment())
.commit();
}
}
/**
* Navigate to the given fragment.
*
* @param fragment Fragment to navigate to.
* @param addToBackstack Whether or not the current fragment should be added to the backstack.
*/
@Override
public void navigateTo(Fragment fragment, boolean addToBackstack) {
FragmentTransaction transaction =
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment);
if (addToBackstack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
}
In dieser Aktivität wird die Layoutdatei R.layout.shr_main_activity
angezeigt, die in shr_main_activity.xml
definiert ist.
In onCreate(),
wird eine Fragment
-Transaktion gestartet, um die LoginFragment
anzuzeigen.MainActivity.java
LoginFragment.
Das ist das, was wir in diesem Codelab ändern werden. Die Aktivität implementiert auch eine navigateTo(Fragment)
-Methode, die in NavigationHost
definiert ist und mit der jedes Fragment zu einem anderen Fragment navigieren kann.
Befehl + Klicken (oder Strg + Klicken) shr_main_activity
in der Aktivitätsdatei, 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 von der Aktivität angezeigten Fragmente dient. Öffnen wir LoginFragment.java
.
LoginFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
/**
* Fragment representing the login screen for Shrine.
*/
public class LoginFragment extends Fragment {
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
// Snippet from "Navigate to the next Fragment" section goes here.
return view;
}
// "isPasswordValid" from "Navigate to the next Fragment" section method goes here
}
LoginFragment
rendert die Layoutdatei shr_login_fragment
und zeigt sie in onCreateView()
an. Sehen wir uns 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" />
<!-- Snippet from "Add text fields" section goes here. -->
<!-- Snippet from "Add buttons" section goes here. -->
</LinearLayout>
</ScrollView>
Hier sehen wir ein <LinearLayout>
mit einem <ImageView>
oben, das das Logo von „Shrine“ darstellt.
Danach folgt ein <TextView>
-Tag, das das Label „SHRINE“ darstellt. Der Text für dieses Label ist eine String-Ressource mit dem Namen @string/shr_app_name
. Wenn Sie Befehl + Klicken (oder Strg + Klicken) auf den Namen der String-Ressource ausführen oder app -> res -> values -> strings.xml
öffnen, sehen Sie die Datei strings.xml
, in der String-Ressourcen definiert sind. Wenn in Zukunft weitere String-Ressourcen 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.
Zuerst fügen wir unserer Anmeldeseite zwei Textfelder hinzu, in die Nutzer ihren Nutzernamen und ihr Passwort eingeben können. Wir verwenden die MDC-Komponente „Textfeld“, die integrierte Funktionen zum Anzeigen eines schwebenden Labels und von Fehlermeldungen enthält.
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>
ein:
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"
android:inputType="text"
android:maxLines="1" />
</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 String-Ressourcen für das Textfeld hinzugefügt: @string/shr_hint_username
und @string/shr_hint_password
. Öffnen Sie strings.xml
, um diese String-Ressourcen aufzurufen.
strings.xml
...
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
...
Eingabevalidierung hinzufügen
TextInputLayout
-Komponenten bieten eine integrierte Funktion für Fehlermeldungen.
Damit Fehlermeldungen angezeigt werden, müssen Sie shr_login_fragment.xml
so ändern:
- Setzen Sie das Attribut
app:errorEnabled
für das Element PasswordTextInputLayout
auf „true“. Dadurch wird unter dem Textfeld zusätzlicher Abstand für die Fehlermeldung eingefügt. - Legen Sie das Attribut
android:inputType
für das Element PasswortTextInputEditText
auf „textPassword
“ fest. Dadurch wird der eingegebene Text im Passwortfeld ausgeblendet.
Nach diesen Änderungen 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"
android:inputType="text"
android:maxLines="1" />
</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>
Führen Sie die App nun aus. Sie sollten eine Seite mit zwei Textfeldern für „Nutzername“ und „Passwort“ sehen.
So sieht die Animation für unverankerte Labels aus:
Als Nächstes fügen wir unserer Anmeldeseite zwei Schaltflächen hinzu: „Abbrechen“ und „Weiter“. Wir verwenden die MDC-Schaltflächenkomponente, die den bekannten Material Design-Tintenwelle-Effekt enthält.
XML hinzufügen
Fügen Sie in shr_login_fragment.xml
dem <LinearLayout>
unter den TextInputLayout
-Elementen ein <RelativeLayout>
hinzu. Fügen Sie dann dem <RelativeLayout>
zwei <MaterialButton>
-Elemente 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>
Geschafft! Wenn Sie die App ausführen, wird beim Tippen auf jede Schaltfläche ein Tinteneffekt angezeigt.
Schließlich fügen wir LoginFragment.java
etwas Java-Code hinzu, um die Schaltfläche „WEITER“ mit einem anderen Fragment zu verknüpfen. Sie sehen, dass jeder der Komponenten, die wir unserem Layout hinzugefügt haben, ein id
zugewiesen wurde. Wir verwenden diese id
, um auf die Komponenten in unserem Code zu verweisen und einige Fehlerprüfungen und Navigationsfunktionen hinzuzufügen.
Fügen wir in LoginFragment.java
unter onCreateView()
eine private boolesche Methode isPasswordValid
mit Logik hinzu, um zu ermitteln, ob das Passwort gültig ist. Für diese Demo prüfen wir nur, ob das Passwort mindestens 8 Zeichen lang ist:
LoginFragment.java
/*
In reality, this will have more complex logic including, but not limited to, actual
authentication of the username and password.
*/
private boolean isPasswordValid(@Nullable Editable text) {
return text != null && text.length() >= 8;
}
Fügen Sie als Nächstes einen Klick-Listener für die Schaltfläche „Weiter“ 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.
Als Nächstes fügen wir dem Passwort-TextInputEditText
einen Key-Listener hinzu, um auf Key-Events zu warten, die den Fehler beheben. Dieser Listener sollte auch isPasswordValid()
verwenden, um zu prüfen, ob das Passwort gültig ist. Sie können diesen Code direkt unter dem Klick-Listener in onCreateView()
hinzufügen.
Ihre onCreateView()-Methode sollte nun in etwa so aussehen:
LoginFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
final TextInputLayout passwordTextInput = view.findViewById(R.id.password_text_input);
final TextInputEditText passwordEditText = view.findViewById(R.id.password_edit_text);
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
}
}
});
// Clear the error once more than 8 characters are typed.
passwordEditText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(null); //Clear the error
}
return false;
}
});
return view;
}
Jetzt können wir zu einem anderen Fragment wechseln. Aktualisieren Sie OnClickListener
in onCreateView()
, um zu einem anderen Fragment zu wechseln, wenn die Fehlerüberprüfung erfolgreich ist. Fügen Sie dazu die folgende Zeile ein, um zum else
-Fall des Click-Listeners zu navigieren:ProductGridFragment
LoginFragment.java
...
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
...
Der Klick-Listener sollte nun so aussehen:
LoginFragment.java
...
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
}
}
});
...
In dieser neuen Codezeile wird die Methode navigateTo()
aus MainActivity
aufgerufen, um zu einem neuen Fragment – ProductGridFragment
– zu wechseln. Derzeit ist dies eine leere Seite, an der Sie in MDC-102 arbeiten werden.
Erstellen Sie nun die App. Klicken Sie dazu auf die Schaltfläche „Weiter“.
Geschafft! Dieser Bildschirm ist der Ausgangspunkt für das nächste Codelab, das Sie in MDC-102 bearbeiten.
Mit der Bibliothek „Material Components for Android“ konnten Sie mit grundlegenden XML-Markups und etwa 30 Zeilen Java-Code eine ansprechende Anmeldeseite erstellen, die den Material Design-Richtlinien entspricht und auf allen Geräten einheitlich aussieht und sich einheitlich verhält.
Weiteres Vorgehen
„Text Field“ (Textfeld) und „Button“ (Schaltfläche) sind zwei Kernkomponenten in der MDC-Android-Bibliothek. Es gibt aber noch viele weitere. Weitere Komponenten in MDC Android 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 ausprobiert haben. Wir hoffen, dieses Codelab hat Ihnen gefallen.