1. Introduzione
I componenti Material (MDC) aiutano 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 |
Che cosa sono Material Design e i componenti Material per Android?
Material Design è un sistema per la creazione di prodotti digitali audaci e accattivanti. Unendo stile, branding, interazione e movimento in un insieme coerente di principi e componenti, i team di prodotto possono realizzare il loro massimo potenziale di progettazione.
Per le applicazioni Android, i componenti Material per Android (MDC Android) uniscono progettazione e ingegneria con una libreria di componenti per creare coerenza nell'applicazione. Man mano che il sistema Material Design si evolve, questi componenti vengono aggiornati per garantire un'implementazione coerente e perfetta a livello di pixel e il rispetto degli standard di sviluppo frontend di Google. MDC è disponibile anche per web, iOS e Flutter.
In questo codelab creerai una pagina di accesso utilizzando diversi componenti di MDC Android.
Che cosa creerai
Questo codelab è il primo di quattro codelab che ti guideranno nella creazione di un'app chiamata Shrine, un'app Android di e-commerce che vende abbigliamento e articoli per la casa. Ti mostrerà come personalizzare i componenti per riflettere qualsiasi brand o stile utilizzando MDC-Android.
In questo codelab creerai una pagina di accesso per Shrine che contiene:
- Due campi di testo, uno per inserire un nome utente e l'altro per una password
- Due pulsanti, uno per "Annulla" e uno per "Avanti"
- Il nome dell'app (Shrine)
- Un'immagine del logo di Shrine

Componenti MDC Android in questo codelab
- Campo di testo
- Pulsante
Che cosa ti serve
- Conoscenze di base dello sviluppo per Android
- Android Studio (scaricalo qui se non lo hai già)
- Un emulatore o un dispositivo Android (disponibile tramite Android Studio)
- Il codice campione (vedi il passaggio successivo)
Come valuteresti il tuo livello di esperienza nella creazione di app per Android?
2. Configurazione dell'ambiente di sviluppo
Avvia Android Studio
Quando apri Android Studio, dovrebbe essere visualizzata una finestra intitolata "Welcome to Android Studio". Tuttavia, se è la prima volta che avvii Android Studio, segui i passaggi della procedura guidata di configurazione di Android Studio con i valori predefiniti. Questo passaggio può richiedere diversi minuti per scaricare e installare i file necessari, quindi puoi lasciarlo in esecuzione in background mentre esegui la sezione successiva.
Scarica l'app di avvio del codelab
L'app di base si trova nella directory material-components-android-codelabs-101-starter/java.
...o clonala da GitHub
Per clonare questo codelab da GitHub, esegui i seguenti comandi:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 101-starter
Carica il codice di avvio in Android Studio
- Una volta completata la procedura guidata di configurazione e visualizzata la finestra Welcome to Android Studio, fai clic su Open an existing Android Studio project. Vai alla directory in cui hai installato il codice campione e seleziona java -> shrine (o cerca shrine sul computer) per aprire il progetto Shrine.
- Attendi qualche istante che Android Studio crei e sincronizzi il progetto, come indicato dagli indicatori di attività nella parte inferiore della finestra di Android Studio.
- 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.
Aggiungi 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 passaggi seguenti per assicurarti che sia così.
- Vai al file
build.gradledel moduloappe assicurati che il bloccodependenciesincluda una dipendenza da MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Facoltativo) Se necessario, modifica il file
build.gradleper aggiungere le seguenti dipendenze e sincronizzare il progetto.
dependencies {
api 'com.google.android.material:material:1.1.0-alpha06'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}
Esegui l'app di base
|
Operazione riuscita. Il codice di avvio per la pagina di accesso di Shrine dovrebbe essere in esecuzione nell'emulatore. Dovresti vedere il nome "Shrine" e il logo di Shrine appena sotto.

Diamo un'occhiata al codice. Nel codice campione abbiamo fornito un semplice framework di navigazione Fragment per visualizzare i fragment e spostarsi tra di essi.
Apri MainActivity.java nella directory shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.java.shrine. Dovrebbe contenere quanto segue:
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();
}
}
Questa attività visualizza il file di layout R.layout.shr_main_activity, definito in shr_main_activity.xml.
Puoi vedere che in onCreate(), MainActivity.java avvia una transazione Fragment per mostrare il LoginFragment. LoginFragment. È questo che modificheremo per questo codelab. L'attività implementa anche un metodo navigateTo(Fragment), definito in NavigationHost, che consente a qualsiasi fragment di passare a un altro fragment.
Premi Command + clic (o Control + clic) shr_main_activity nel file di attività per aprire il file di layout oppure vai al file di layout in app -> res -> layout -> shr_main_activity.xml.
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" />
Qui vediamo un semplice <FrameLayout> che funge da contenitore per tutti i fragment visualizzati dall'attività. Apriamo 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 espande il file di layout shr_login_fragment e lo visualizza in onCreateView(). Diamo un'occhiata al file di layout shr_login_fragment.xml per vedere come appare la pagina di accesso.
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>
Qui possiamo vedere un <LinearLayout> con un <ImageView> nella parte superiore, che rappresenta il logo "Shrine".
Di seguito è riportato un tag <TextView> che rappresenta l'etichetta "SHRINE". Il testo di questa etichetta è una risorsa stringa denominata @string/shr_app_name. Se fai Command + clic (o Control + clic) sul nome della risorsa stringa o apri app -> res -> values -> strings.xml, puoi vedere il file strings.xml in cui sono definite le risorse stringa. Quando in futuro verranno aggiunte altre risorse stringa, verranno definite qui. Ogni risorsa in questo file deve avere un prefisso shr_ per indicare che fa parte dell'app Shrine.
Ora che hai familiarità con il codice di avvio, implementiamo il nostro primo componente.
3. Aggiungi campi di testo
Per iniziare, aggiungeremo due campi di testo alla nostra pagina di accesso in cui gli utenti potranno inserire il nome utente e la password. Utilizzeremo il componente Campo di testo MDC, che include funzionalità integrate che visualizzano un'etichetta mobile e messaggi di errore.

Aggiungi l'XML
In shr_login_fragment.xml, aggiungi due elementi TextInputLayout con un elemento secondario TextInputEditText all'interno di <LinearLayout>, sotto l'etichetta ""SHRINE"" di <TextView>:
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>
Lo snippet precedente rappresenta due campi di testo, ognuno composto da un elemento <TextInputLayout> e un elemento secondario <TextInputEditText>. Il testo di suggerimento per ogni campo di testo è specificato nell'attributo android:hint.
Abbiamo incluso due nuove risorse stringa per il campo di testo: @string/shr_hint_username e @string/shr_hint_password. Apri strings.xml per visualizzare queste risorse stringa.
strings.xml
...
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
...
Aggiungi la convalida dell'input
I componenti TextInputLayout forniscono funzionalità di feedback sugli errori integrate.
Per mostrare il feedback sugli errori, apporta le seguenti modifiche a shr_login_fragment.xml:
- Imposta l'attributo
app:errorEnabledsu true nell'elemento PasswordTextInputLayout. In questo modo verrà aggiunta una spaziatura interna extra per il messaggio di errore sotto il campo di testo. - Imposta l'attributo
android:inputTypesu "textPassword" nell'elemento PasswordTextInputEditText. In questo modo il testo di input nel campo della password verrà nascosto.
Con queste modifiche, i campi di testo in shr_login_fragment.xml dovrebbero avere il seguente aspetto:
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>
Ora prova a eseguire l'app. Dovresti vedere una pagina con due campi di testo per "Nome utente" e "Password".
Dai un'occhiata all'animazione dell'etichetta mobile:

4. Aggiungi pulsanti
Successivamente, aggiungeremo due pulsanti alla nostra pagina di accesso: "Annulla" e "Avanti". Utilizzeremo il componente Pulsante MDC, che include l'iconico effetto di increspatura dell'inchiostro di Material Design.

Aggiungi l'XML
In shr_login_fragment.xml, aggiungi un <RelativeLayout> a <LinearLayout>, sotto gli elementi TextInputLayout. Poi aggiungi due elementi <MaterialButton> a <RelativeLayout>.
Il file XML risultante dovrebbe avere il seguente aspetto:
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>
Questo è tutto. Quando esegui l'app, verrà visualizzata un'increspatura dell'inchiostro quando tocchi ogni pulsante.

5. Vai al fragment successivo
Infine, aggiungeremo del codice Java a LoginFragment.java per collegare il pulsante "AVANTI" a un altro fragment. Noterai che a ognuno dei componenti che abbiamo aggiunto al layout è stato assegnato un id. Utilizzeremo questi id per fare riferimento ai componenti nel nostro codice e aggiungere alcuni controlli degli errori e la navigazione.
Aggiungiamo un metodo booleano privato isPasswordValid in LoginFragment.java sotto onCreateView(), con la logica per determinare se la password è valida o meno. Ai fini di questa demo, ci assicureremo solo che la password contenga almeno 8 caratteri:
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;
}
Poi aggiungi un listener di clic al pulsante "Avanti" che imposta e cancella l'errore in base al metodo isPasswordValid() che abbiamo appena creato. In onCreateView(), questo click listener deve essere inserito tra la riga di espansione e la riga return view.
Poi aggiungiamo un listener di tasti a TextInputEditText della password per ascoltare gli eventi di tasti che cancellerebbero l'errore. Questo listener deve utilizzare anche isPasswordValid() per verificare se la password è valida o meno. Puoi aggiungerlo direttamente sotto il listener di clic in onCreateView().
Il metodo onCreateView() dovrebbe ora avere un aspetto simile al seguente:
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;
}
Ora possiamo passare a un altro fragment. Aggiorna OnClickListener in onCreateView() per passare a un altro fragment quando la convalida degli errori ha esito positivo. Per farlo, aggiungi la seguente riga per passare a ProductGridFragment al caso else del click listener:
LoginFragment.java
...
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
...
Il click listener dovrebbe ora avere il seguente aspetto:
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
}
}
});
...
Questa nuova riga di codice chiama il metodo navigateTo() da MainActivity per passare a un nuovo fragment: ProductGridFragment. Al momento si tratta di una pagina vuota su cui lavorerai in MDC-102.
Ora crea l'app. Premi il pulsante Avanti.
Ce l'hai fatta. Questa schermata sarà il punto di partenza del nostro prossimo codelab su cui lavorerai in MDC-102.
6. Fine
Utilizzando il markup XML di base e circa 30 righe di Java, la libreria dei componenti Material per Android ti ha aiutato a creare una pagina di accesso accattivante che rispetta le linee guida di Material Design e che ha un aspetto e un comportamento coerenti su tutti i dispositivi.
Passaggi successivi
Il campo di testo e il pulsante sono due componenti principali della libreria MDC Android, ma ce ne sono molti altri. Puoi esplorare il resto dei componenti in MDC Android. In alternativa, vai a MDC 102: struttura e layout di Material Design per scoprire di più sulla barra dell'app principale, sulla visualizzazione schede e sul layout a griglia. Grazie per aver provato i componenti Material. Speriamo che questo codelab ti sia piaciuto.