1. Introduzione
Material Design è un sistema per la creazione di prodotti digitali belli e audaci. 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.
Material Components (MDC) consente agli sviluppatori di implementare Material Design. Creato dal team di ingegneri e designer UX di Google, MDC è dotato di decine di componenti UI belli e funzionali ed è disponibile per Android, iOS, web e Flutter.material.io/develop |
Cos'è il sistema di movimento di Material per Android?
Il sistema di movimento Material per Android è un insieme di modelli di transizione all'interno della libreria MDC-Android che possono aiutare gli utenti a comprendere e navigare in un'app, come descritto nelle linee guida di Material Design.
I quattro principali modelli di transizione Material sono i seguenti:
- Trasformazione container: transizioni tra elementi UI che includono un contenitore. crea una connessione visibile tra due elementi distinti dell'interfaccia utente trasformando in modo fluido un elemento in un altro.
- Asse condiviso: transizioni tra elementi UI che hanno una relazione spaziale o di navigazione. utilizza una trasformazione condivisa sugli assi x, y o z per rafforzare la relazione tra gli elementi.
- Dissolvenza attraverso: transizioni tra elementi UI che non hanno una forte relazione tra loro. utilizza una dissolvenza in entrata e in uscita sequenziale, con una scala dell'elemento in entrata.
- Dissolvenza: utilizzata per gli elementi UI che entrano o escono entro i margini dello schermo.
La libreria MDC-Android offre classi di transizione per questi pattern, basate sia sulla libreria AndroidX Transizione (androidx.transition
) sia su Android Transizione Framework (android.transition
):
AndroidX
- Disponibile nel pacchetto
com.google.android.material.transition
- Supporta il livello API 14 o versioni successive
- Supporta frammenti e viste, ma non attività o finestre
- Contiene correzioni di bug con backporting e un comportamento coerente tra i livelli API
Framework
- Disponibile nel pacchetto
com.google.android.material.transition.platform
- Supporta il livello API 21 o versioni successive
- Supporta frammenti, viste, attività e finestre
- Correzioni di bug non sottoposte a backporting e che potrebbero avere comportamenti diversi nei livelli API
In questo codelab, utilizzerai le transizioni Material basate sulla libreria AndroidX, il che significa che ti concentrerai principalmente su Frammenti e Viste.
Cosa creerai
Questo codelab ti guiderà nella creazione di alcune transizioni in un'app email per Android di esempio chiamata Rispondi, utilizzando Kotlin, per dimostrare come utilizzare le transizioni dalla libreria MDC-Android per personalizzare l'aspetto e il design della tua app.
Ti verrà fornito il codice di avvio per l'app di Reply e incorporerai nell'app le seguenti transizioni di tipo Material, che puoi vedere nella GIF completa del codelab qui sotto:
- Transizione di Container Transform dalla mailing list alla pagina dei dettagli delle email
- Transizione di Container Transform da FAB alla pagina di scrittura delle email
- Transizione sull'asse Z condivisa dall'icona di ricerca alla pagina di visualizzazione della ricerca
- Transizione Dissolvenza attraverso tra le pagine delle caselle di posta
- Transizione di Container Transform dal chip di indirizzo email alla visualizzazione schede
Che cosa ti serve
- Conoscenza di base dello sviluppo Android e di Kotlin
- Android Studio (scaricalo qui se non l'hai ancora fatto)
- Un emulatore o un dispositivo Android (disponibile tramite Android Studio)
- Il codice di esempio (vedi il passaggio successivo)
Come giudichi il tuo livello di esperienza nello sviluppo di app per Android?
2. Configurazione dell'ambiente di sviluppo
Avvia Android Studio
Quando apri Android Studio, dovrebbe essere visualizzata una finestra chiamata "Ti diamo il benvenuto in Android Studio". Tuttavia, se è la prima volta che avvii Android Studio, segui la procedura della Configurazione guidata di Android Studio con i valori predefiniti. Questo passaggio può richiedere diversi minuti per scaricare e installare i file necessari, quindi non esitare a lasciarlo in esecuzione in background mentre esegui la prossima sezione.
Opzione 1: clona l'app codelab iniziale da GitHub
Per clonare questo codelab da GitHub, esegui questi comandi:
git clone https://github.com/material-components/material-components-android-motion-codelab.git cd material-components-android-motion-codelab
Opzione 2: scarica il file ZIP dell'app codelab iniziale
L'app iniziale si trova nella directory material-components-android-motion-codelab-develop
.
Carica il codice di avvio in Android Studio
- Al termine della configurazione guidata e visualizzata la finestra Ti diamo il benvenuto in Android Studio, fai clic su Apri un progetto Android Studio esistente.
- Passa alla directory in cui hai installato il codice di esempio e selezionala per aprire il progetto.
- Attendi un momento affinché Android Studio crei e sincronizzi il progetto, come mostrato dagli indicatori di attività nella parte inferiore della finestra di Android Studio.
- A questo punto, Android Studio potrebbe generare alcuni errori di generazione perché non disponi dell'SDK Android o degli strumenti di sviluppo, come quello mostrato di seguito. Segui le istruzioni in Android Studio per installarle/aggiornarle e sincronizzare il progetto. Se i problemi persistono, segui la guida sull'aggiornamento degli strumenti con SDK Manager.
Verifica le dipendenze del progetto
Il progetto richiede una dipendenza dalla libreria MDC-Android. Nel codice campione che hai scaricato dovrebbe già essere presente questa dipendenza, ma per scoprirlo diamo un'occhiata alla configurazione.
Passa al file build.gradle
del modulo app
e assicurati che il blocco dependencies
includa una dipendenza su MDC-Android:
implementation 'com.google.android.material:material:1.2.0'
Esegui l'app iniziale
- Assicurati che la configurazione della build a sinistra del dispositivo scelto sia
app
. - Premi il pulsante Esegui / Riproduci verde per creare ed eseguire l'app.
- Se tra i dispositivi disponibili è già elencato un dispositivo Android, nella finestra Seleziona la destinazione del deployment vai al passaggio 8. In caso contrario, fai clic su Crea nuovo dispositivo virtuale.
- Nella schermata Seleziona hardware, seleziona uno smartphone, ad esempio Pixel 3, quindi fai clic su Avanti.
- Nella schermata Immagine di sistema, seleziona una versione di Android recente, preferibilmente il livello API più elevato. Se non è installata, fai clic sul link Scarica visualizzato e completa il download.
- Fai clic su Avanti.
- Nella schermata Dispositivo virtuale Android, lascia le impostazioni invariate e fai clic su Fine.
- Seleziona un dispositivo Android dalla finestra di dialogo della destinazione dell'implementazione.
- Fai clic su Ok.
- Android Studio crea l'app, la distribuisce e la apre automaticamente sul dispositivo di destinazione.
Operazione riuscita. Il codice di avvio per la home page di Reply dovrebbe essere in esecuzione nell'emulatore. Dovresti vedere la Posta in arrivo contenente un elenco di email.
(Facoltativo) Rallentare le animazioni del dispositivo
Dal momento che questo codelab prevede transizioni rapide, ma molto raffinate, può essere utile rallentare le animazioni del dispositivo per osservare alcuni dettagli più minuti delle transizioni durante l'implementazione. A tale scopo, puoi usare i comandi della shell adb
o un riquadro Impostazioni rapide. Tieni presente che questi metodi per rallentare le animazioni del dispositivo influiranno anche sul dispositivo al di fuori dell'app di risposta.
Metodo 1: comandi shell ADB
Per rallentare le animazioni del dispositivo di un fattore di 10 volte, puoi eseguire i seguenti comandi dalla riga di comando:
adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
Per ripristinare la velocità di animazione normale del dispositivo, esegui i seguenti comandi:
adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1
Metodo 2: riquadro Impostazioni rapide
In alternativa, per configurare il riquadro Impostazioni rapide, abilita prima le Impostazioni sviluppatore sul tuo dispositivo se non l'hai ancora fatto:
- Apri "Impostazioni" sul dispositivo. app
- Scorri fino in fondo e fai clic su "Informazioni sul dispositivo emulato"
- Scorri fino in fondo e fai clic rapidamente su "Numero build". fino all'attivazione delle impostazioni sviluppatore
Quindi, svolgi le seguenti operazioni, sempre nelle "Impostazioni" del dispositivo per abilitare il riquadro Impostazioni rapide:
- Fai clic sull'icona di ricerca o sulla barra di ricerca nella parte superiore dello schermo.
- Digita "riquadri" nel campo di ricerca
- Fai clic sui "Riquadri sviluppatore Impostazioni rapide" riga
- Fai clic sulla "Scala dell'animazione finestra" passaggio
Infine, durante il codelab, trascina verso il basso l'area notifiche di sistema dalla parte superiore dello schermo e utilizza l'icona per passare dalle animazioni a velocità normale a quella lenta.
3. Acquisisci familiarità con il codice dell'app di esempio
Diamo un'occhiata al codice. Abbiamo fornito un'app che utilizza la libreria del componente Navigazione Jetpack per navigare tra diversi Frammenti, il tutto all'interno di una singola attività, MainActivity:
- HomeFragment:mostra un elenco di email
- EmailFragment: visualizza una singola email completa
- ComposeFragment:consente di comporre una nuova email.
- SearchFragment: mostra una visualizzazione della ricerca
navigation_graph.xml
Innanzitutto, per capire come è configurato il grafico di navigazione dell'app, apri navigation_graph.xml
nella directory app -> src -> main -> res -> navigation
:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.materialstudies.reply.ui.home.HomeFragment"
android:label="HomeFragment">
<argument...>
<action
android:id="@+id/action_homeFragment_to_emailFragment"
app:destination="@id/emailFragment" />
</fragment>
<fragment
android:id="@+id/emailFragment"
android:name="com.materialstudies.reply.ui.email.EmailFragment"
android:label="EmailFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/composeFragment"
android:name="com.materialstudies.reply.ui.compose.ComposeFragment"
android:label="ComposeFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="com.materialstudies.reply.ui.search.SearchFragment"
android:label="SearchFragment" />
<action
android:id="@+id/action_global_homeFragment"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/navigation_graph"
app:popUpToInclusive="true"/>
<action
android:id="@+id/action_global_composeFragment"
app:destination="@+id/composeFragment" />
<action
android:id="@+id/action_global_searchFragment"
app:destination="@+id/searchFragment" />
</navigation>
Prendi nota di come sono presenti tutti i frammenti menzionati sopra, con il frammento di lancio predefinito impostato su HomeFragment
tramite app:startDestination="@id/homeFragment"
. Questa definizione XML del grafico di destinazione del frammento, così come le azioni, informa il codice di navigazione Kotlin generato che incontrerai durante il collegamento delle transizioni.
activity_main.xml
Ora dai un'occhiata al layout activity_main.xml
nella directory app -> src -> main -> res -> layout
. Vedrai il NavHostFragment
che è configurato con il grafico di navigazione in alto:
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph"/>
Questo NavHostFragment
riempie lo schermo e gestisce tutte le modifiche alla navigazione dei frammenti a schermo intero nell'app. Il BottomAppBar
e il relativo FloatingActionButton
ancorato, anch'esso in activity_main.xml
, sono posizionati sopra il frammento corrente visualizzato da NavHostFragment
e pertanto verranno mostrati o nascosti a seconda della destinazione del frammento dal codice dell'app di esempio fornito.
Inoltre, il BottomNavDrawerFragment
in activity_main.xml
è un riquadro a scomparsa in basso che contiene un menu per navigare tra le diverse caselle di posta email, che viene mostrato in modo condizionale tramite il pulsante con il logo Rispondi di BottomAppBar
.
MainActivity.kt
Infine, per vedere un esempio di un'azione di navigazione in uso, apri MainActivity.kt
nella directory app -> src -> main -> java -> com.materialstudies.reply.ui
. Individua la funzione navigateToSearch()
, che dovrebbe avere il seguente aspetto:
private fun navigateToSearch() {
val directions = SearchFragmentDirections.actionGlobalSearchFragment()
findNavController(R.id.nav_host_fragment).navigate(directions)
}
Questo mostra come raggiungere la pagina di visualizzazione della ricerca senza alcuna transizione personalizzata. Nel corso di questo codelab, analizzerai la MainActivity di Reply e quattro frammenti principali per configurare transizioni Material che funzionino in tandem con le varie azioni di navigazione nell'app.
Ora che hai acquisito familiarità con il codice di base, implementiamo la nostra prima transizione.
4. Aggiungi la transizione Container Transform dalla mailing list alla pagina dei dettagli dell'email
Per iniziare, aggiungerai una transizione quando fai clic su un'email. Per questa modifica alla navigazione, il pattern di trasformazione del container è adatto poiché è progettato per le transizioni tra elementi UI che includono un container. Questo pattern crea una connessione visibile tra due elementi UI.
Prima di aggiungere il codice, prova a eseguire l'app di risposta e a fare clic su un'email. Deve eseguire un semplice jump cut, che consente di sostituire lo schermo senza transizione:
Inizia aggiungendo un attributo transitionName
in MaterialCardView
in email_item_layout.xml
, come mostrato nel seguente snippet:
email_item_layout.xml
android:transitionName="@{@string/email_card_transition_name(email.id)}"
Il nome della transizione include una risorsa stringa con un parametro. Devi utilizzare l'ID di ogni email per assicurarti che ogni transitionName
nel nostro EmailFragment
sia univoco.
Ora che hai impostato il nome della transizione dell'elemento della tua mailing list, ripetiamo la stessa operazione nel layout dei dettagli email. In fragment_email.xml
, imposta transitionName
di MaterialCardView
sulla seguente risorsa stringa:
fragment_email.xml
android:transitionName="@string/email_card_detail_transition_name"
In HomeFragment.kt
, sostituisci il codice in onEmailClicked
con lo snippet riportato di seguito per creare la mappatura dalla vista iniziale (elemento dell'elenco email) e dalla vista finale (schermata dei dettagli email):
HomeFragment.kt
val emailCardDetailTransitionName = getString(R.string.email_card_detail_transition_name)
val extras = FragmentNavigatorExtras(cardView to emailCardDetailTransitionName)
val directions = HomeFragmentDirections.actionHomeFragmentToEmailFragment(email.id)
findNavController().navigate(directions, extras)
Ora che hai configurato l'impianto idraulico, puoi creare una trasformazione del container. Nel metodo onCreate
EmailFragment
, imposta sharedElementEnterTransition
su una nuova istanza di MaterialContainerTransform
(importando la versione com.google.android.material.transition
anziché la versione com.google.android.material.transition.platform
) aggiungendo il seguente snippet:
EmailFragment.kt
sharedElementEnterTransition = MaterialContainerTransform().apply {
drawingViewId = R.id.nav_host_fragment
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
setAllContainerColors(requireContext().themeColor(R.attr.colorSurface))
}
Ora prova a eseguire di nuovo l'app.
Tutto inizia a essere bello! Quando fai clic su un'email nella mailing list, una trasformazione del contenitore dovrebbe espandere l'elemento dell'elenco in una pagina dei dettagli a schermo intero. Nota, però, che premendo Indietro l'email non viene compressa nuovamente nell'elenco. Inoltre, la mailing list scompare immediatamente all'inizio della transizione e viene mostrato lo sfondo grigio della finestra. Quindi non abbiamo ancora finito.
Per correggere la transizione di ritorno, aggiungi le due righe seguenti al metodo onViewCreated
in HomeFragment.kt
:
HomeFragment.kt
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
Prova a eseguire di nuovo l'app. Se premi Indietro dopo l'apertura di un'email, l'email verrà compressa di nuovo nell'elenco. Bene! Continuiamo a migliorare l'animazione.
Il problema della scomparsa della mailing list è che, quando accedi a un nuovo Frammento utilizzando il componente di navigazione, il frammento corrente viene immediatamente rimosso e sostituito con il nostro nuovo Frammento in arrivo. Per mantenere visibile la mailing list anche dopo la sostituzione, puoi aggiungere una transizione di uscita a HomeFragment
.
Aggiungi lo snippet seguente al metodo HomeFragment
onEmailClicked
per fare in modo che l'elenco delle email venga ridotto leggermente all'uscita e viceversa:
HomeFragment.kt
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Successivamente, per assicurarti che la transizione MaterialElevationScale
venga applicata alla schermata Home nel suo complesso, anziché a ogni singola visualizzazione della gerarchia, contrassegna RecyclerView
in fragment_home.xml
come gruppo di transizione.
fragment_home.xml
android:transitionGroup="true"
In questa fase, dovresti avere una trasformazione del container completamente funzionante. Se fai clic su un'email, l'elemento dell'elenco si espande in una schermata dei dettagli, mentre restringi l'elenco di email. Se si preme Indietro, la schermata dei dettagli dell'email torna a essere visualizzata nell'elenco mentre viene fatto lo scale up nell'elenco delle email.
5. Aggiungi la transizione Container Transform da FAB alla pagina di scrittura delle email
Continuiamo con la trasformazione del container e aggiungiamo una transizione dal pulsante di azione mobile a ComposeFragment
, espandendo il FAB a una nuova email che l'utente deve scrivere. Innanzitutto, esegui di nuovo l'app e fai clic sul FAB per vedere che non ci sono transizioni all'avvio della schermata di scrittura dell'email.
Anche se utilizziamo la stessa classe di transizione, il modo in cui configuriamo questa istanza sarà diverso perché il nostro FAB si trova in MainActivity
e il nostro ComposeFragment
è posizionato all'interno del container host di navigazione MainActivity
.
In ComposeFragment.kt
, aggiungi il seguente snippet al metodo onViewCreated
, assicurandoti di importare la versione androidx.transition
di Slide
.
ComposeFragment.kt
enterTransition = MaterialContainerTransform().apply {
startView = requireActivity().findViewById(R.id.fab)
endView = emailCardView
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
containerColor = requireContext().themeColor(R.attr.colorSurface)
startContainerColor = requireContext().themeColor(R.attr.colorSecondary)
endContainerColor = requireContext().themeColor(R.attr.colorSurface)
}
returnTransition = Slide().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_medium).toLong()
addTarget(R.id.email_card_view)
}
Oltre ai parametri utilizzati per configurare la precedente trasformazione del container, startView
e endView
vengono impostati manualmente qui. Anziché utilizzare gli attributi transitionName
per indicare al sistema di transizione Android quali viste devono essere trasformate, puoi specificarle manualmente quando necessario.
Ora esegui di nuovo l'app. Dovresti vedere il FAB che si trasforma nella schermata di composizione (vedi la GIF alla fine di questo passaggio).
Come nel passaggio precedente, devi aggiungere una transizione a HomeFragment
per evitare che scompaia dopo essere stato rimosso e sostituito con ComposeFragment
.
Copia lo snippet riportato di seguito nel metodo navigateToCompose
in MainActivity
prima della chiamata NavController
navigate
.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
Questo è tutto. Dovresti avere una transizione dal FAB per creare una schermata di composizione simile alla seguente:
6. Aggiungi la transizione sull'asse Z condivisa dall'icona di ricerca alla pagina di visualizzazione della ricerca
In questo passaggio, aggiungeremo una transizione dall'icona di ricerca alla visualizzazione della ricerca a schermo intero. Poiché questa modifica alla navigazione non prevede un container permanente, possiamo utilizzare una transizione sull'asse Z condiviso per rafforzare la relazione spaziale tra le due schermate e indicare lo spostamento di un livello verso l'alto nella gerarchia dell'app.
Prima di aggiungere altro codice, prova a eseguire l'app e a toccare l'icona di ricerca nell'angolo in basso a destra dello schermo. Dovrebbe apparire la schermata di visualizzazione della ricerca senza transizione.
Per iniziare, trova il metodo navigateToSearch
in MainActivity
e aggiungi il seguente snippet di codice prima della chiamata al metodo navigate
NavController
per configurare l'uscita del frammento corrente e reinserire MaterialSharedAxis
transizioni sull'asse Z.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
Successivamente, aggiungi il seguente snippet di codice al metodo onCreate
in SearchFragment
, che configura le transizioni Invio e Restituisci MaterialSharedAxis
.
SearchFragment.kt
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Infine, per assicurarti che la transizione MaterialSharedAxis
venga applicata alla schermata di ricerca nel suo complesso, invece che a ogni singola visualizzazione della gerarchia, contrassegna LinearLayout
in fragment_search.xml
come gruppo di transizione.
fragment_search.xml
android:transitionGroup="true"
È tutto. Ora prova a eseguire di nuovo l'app e a toccare l'icona di ricerca. Le schermate Home e Ricerca devono contemporaneamente sfocare e ridimensionare in profondità l'asse Z, creando un effetto omogeneo tra le due schermate.
7. Aggiungi una transizione Fade-through tra le pagine delle caselle di posta
In questo passaggio aggiungeremo una transizione tra diverse caselle di posta. Poiché non vogliamo enfatizzare una relazione spaziale o gerarchica, utilizzeremo una dissolvenza attraverso per eseguire un semplice "swap" tra gli elenchi di email.
Prima di aggiungere altro codice, prova a eseguire l'app, a toccare il logo Rispondi nella barra delle app in basso e a cambiare casella di posta. L'elenco delle email dovrebbe cambiare senza transizione.
Per iniziare, trova il metodo navigateToHome
in MainActivity
e aggiungi il seguente snippet di codice prima della chiamata al metodo navigate
NavController
per impostare la transizione MaterialFadeThrough
di uscita del frammento corrente.
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
Dopodiché apri HomeFragment
. In onCreate
, imposta il valore enterTransition
del frammento su una nuova istanza di MaterialFadeThrough
.
HomeFragment.kt
enterTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
Esegui di nuovo l'app. Quando apri il riquadro di navigazione a scomparsa in basso e cambi le caselle di posta, l'elenco corrente di email dovrebbe scomparire e fare lo scale out, mentre il nuovo elenco appare in dissolvenza e viene scalato. Bene!
8. Aggiungi la transizione Container Transform dal chip dell'indirizzo email alla visualizzazione schede
In questo passaggio, aggiungerai una transizione che trasforma un chip in una scheda popup. Qui viene utilizzata una trasformazione del contenitore per informare l'utente che l'azione intrapresa nel popup influirà sul chip da cui ha avuto origine il popup.
Prima di aggiungere codice, esegui l'app di risposta, fai clic su un'email, fai clic sulla risposta FAB, quindi prova a fare clic sul chip di contatto di un destinatario. Il chip dovrebbe scomparire immediatamente e dovrebbe apparire una scheda con gli indirizzi email di quel contatto, senza animazioni.
Lavorerai in ComposeFragment
per questo passaggio. Nel layout ComposeFragment
sono già stati aggiunti i chip dei destinatari (visibili per impostazione predefinita) e una scheda del destinatario (invisibili per impostazione predefinita). Un chip destinatario e questa scheda sono le due visualizzazioni tra le quali creerai una trasformazione contenitore.
Per iniziare, apri ComposeFragment
e trova il metodo expandChip
. Questo metodo viene chiamato quando l'utente fa clic sull'elemento chip
fornito. Aggiungi il seguente snippet di codice sopra le righe che scambiano la visibilità recipientCardView
e chip
, che attiverà la trasformazione del container registrata tramite beginDelayedTransition
.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = chip
endView = binding.recipientCardView
scrimColor = Color.TRANSPARENT
endElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(binding.recipientCardView)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
Se esegui l'app ora, il chip dovrebbe trasformarsi in una scheda di indirizzi email per il destinatario. A questo punto configuriamo la transizione di ritorno per comprimere di nuovo la scheda nel chip.
Nel metodo collapseChip
in ComposeFragment
, aggiungi lo snippet di codice riportato di seguito per comprimere la scheda nel chip.
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = binding.recipientCardView
endView = chip
scrimColor = Color.TRANSPARENT
startElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(chip)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
Esegui di nuovo l'app. Se fai clic sul chip, il chip dovrebbe espanderlo in una scheda, mentre se fai clic sulla scheda la scheda verrà compressa di nuovo all'interno del chip. Bene!
9. Fine
Utilizzando meno di 100 righe di codice Kotlin e un markup XML di base, la libreria MDC-Android ti ha aiutato a creare bellissime transizioni in un'app esistente conforme alle linee guida di Material Design, oltre che avere un aspetto e un comportamento coerenti su tutti i dispositivi Android.
Passaggi successivi
Per ulteriori informazioni sul sistema di movimento Material, assicurati di consultare le specifiche e la documentazione completa per gli sviluppatori, quindi prova ad aggiungere alcune transizioni Material alla tua app.
Grazie per aver provato Material motion. Speriamo che questo codelab ti sia piaciuto.