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 |
Che cos'è il sistema di movimento di Material per Android?
Il sistema di movimento Material per Android è un insieme di pattern di transizione all'interno della libreria MDC-Android che può 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 del contenitore: transizioni tra elementi dell'interfaccia utente che includono un contenitore. Crea un collegamento visibile tra due elementi dell'interfaccia utente distinti trasformando facilmente un elemento in un altro.
- Asse condiviso: transizioni tra elementi dell'interfaccia utente che hanno una relazione spaziale o di navigazione; utilizza una trasformazione condivisa sull'asse x, y o z per rafforzare la relazione tra gli elementi.
- Dissolvenza tramite: transizioni tra elementi dell'interfaccia utente che non hanno una forte correlazione tra loro. Utilizza una dissolvenza in entrata e in uscita sequenziale, con una scala dell'elemento in entrata.
- Dissolvenza: utilizzata per gli elementi dell'interfaccia utente che entrano o escono dalle estremità della schermata.
La libreria MDC-Android offre classi di transizione per questi pattern, basate sia sulla libreria AndroidX Transition (androidx.transition
) sia sul framework Android Transition (android.transition
):
AndroidX
- Disponibile nel pacchetto
com.google.android.material.transition
- Supporta il livello API 14 e versioni successive
- Supporta frammenti e visualizzazioni, ma non attività o finestre
- Contiene correzioni di bug backported e comportamento coerente tra i livelli API
Framework
- Disponibile nel pacchetto
com.google.android.material.transition.platform
- Supporta il livello API 21 e versioni successive
- Supporta frammenti, viste, attività e finestre
- Le correzioni di bug non sono state sottoposte a backporting e potrebbero avere un comportamento diverso nei vari livelli API
In questo codelab utilizzerai le transizioni Material create sulla base della 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 di posta elettronica Android di esempio chiamata Rispondi, utilizzando Kotlin, per dimostrare come puoi utilizzare le transizioni della libreria MDC-Android per personalizzare l'aspetto della tua app.
Ti verrà fornito il codice di avvio dell'app Reply e dovrai incorporare le seguenti transizioni Material nell'app, che puoi vedere nella GIF del codelab completato di seguito:
- 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 dell'asse Z condivisa dall'icona di ricerca alla pagina di visualizzazione della ricerca
- Transizione Dissolvenza tra le pagine della casella di posta
- Transizione di Container Transform dal chip dell'indirizzo email alla visualizzazione scheda
Che cosa ti serve
- Conoscenza di base dello sviluppo Android e di Kotlin
- Android Studio (scaricalo qui se non lo hai già)
- Un emulatore o un dispositivo Android (disponibile tramite Android Studio)
- Il codice di esempio (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 la finestra "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 del codelab di avvio
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 viene 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 per consentire ad Android Studio di compilare e sincronizzare il progetto, come indicato dagli indicatori di attività nella parte inferiore della finestra di Android Studio.
- A questo punto, Android Studio potrebbe segnalare alcuni errori di compilazione perché mancano gli strumenti di compilazione o l'SDK Android, come quello mostrato di seguito. Segui le istruzioni in Android Studio per installare/aggiornare questi componenti 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. Il codice di esempio che hai scaricato dovrebbe già avere questa dipendenza elencata, ma diamo un'occhiata alla configurazione per assicurarci.
Vai al file build.gradle
del modulo app
e assicurati che il blocco dependencies
includa una dipendenza da MDC-Android:
implementation 'com.google.android.material:material:1.2.0'
Esegui l'app iniziale
- Assicurati che la configurazione di compilazione a sinistra della scelta del dispositivo 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 è installato, 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 Destinazione di deployment.
- 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
Poiché questo codelab prevede transizioni rapide, ma raffinate, può essere utile rallentare le animazioni del dispositivo per osservare alcuni dei dettagli più fini 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 sulle animazioni del dispositivo al di fuori dell'app Reply.
Metodo 1: comandi shell ADB
Per rallentare le animazioni del dispositivo 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 l'app "Impostazioni" del dispositivo.
- Scorri fino in fondo e fai clic su "Informazioni sul dispositivo emulato"
- Scorri fino in fondo e fai clic rapidamente su "Numero build" finché non vengono attivate le Impostazioni sviluppatore
Per attivare il riquadro delle Impostazioni rapide, procedi nel seguente modo, sempre all'interno dell'app "Impostazioni" del dispositivo:
- Fai clic sull'icona di ricerca o sulla barra di ricerca nella parte superiore dello schermo.
- Digita "riquadri" nel campo di ricerca
- Fai clic sulla riga "Riquadri sviluppatore per le Impostazioni rapide".
- Fai clic sull'opzione "Scala animazione finestra"
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: mostra un'unica email completa
- ComposeFragment: consente la composizione di una nuova email
- SearchFragment: mostra una visualizzazione della ricerca
navigation_graph.xml
Innanzitutto, per capire come è configurato il grafo 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>
Tieni presente che tutti i frammenti sopra menzionati sono presenti, 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 NavHostFragment
configurato con il grafico di navigazione dall'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 relative alla navigazione dei frammenti a schermo intero nell'app. Il BottomAppBar
e i suoi FloatingActionButton
ancorati, anch'essi 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 puoi passare alla pagina della 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. Aggiungere la transizione di Container Transform dall'elenco email 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 in quanto è progettato per le transizioni tra elementi UI che includono un container. Questo pattern crea una connessione visibile tra due elementi UI.
Prima di aggiungere qualsiasi codice, prova a eseguire l'app Rispondi e fai 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 accetta 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 di transizione dell'elemento dell'elenco email, fai lo stesso nel layout dei dettagli dell'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 seguente per creare la mappatura dalla visualizzazione iniziale (elemento dell'elenco di email) e dalla visualizzazione finale (schermata dei dettagli dell'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.
Sembra che tutto stia andando per il meglio. Quando fai clic su un'email nell'elenco, una trasformazione del contenitore dovrebbe espandere l'elemento dell'elenco in una pagina dei dettagli a schermo intero. Tuttavia, tieni presente che premendo Indietro l'email non viene compressa di nuovo nell'elenco. Inoltre, l'elenco di email scompare immediatamente all'inizio della transizione, mostrando 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 aver aperto un'email, l'email verrà compressa di nuovo nell'elenco. Bene! Continuiamo a migliorare l'animazione.
Il problema della scomparsa dell'elenco di email si verifica perché, quando si passa a un nuovo frammento utilizzando il componente di navigazione, il frammento corrente viene immediatamente rimosso e sostituito dal 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 e l'elenco delle email si riduce. 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 contenitore e aggiungiamo una transizione dal pulsante di azione mobile a ComposeFragment
, espandendo il pulsante di azione mobile in una nuova email da scrivere dall'utente. Innanzitutto, esegui di nuovo l'app e fai clic sul FAB per verificare che non ci sia alcuna transizione quando viene lanciata la schermata di composizione dell'email.
Sebbene utilizziamo lo stesso metodo di transizione, il modo in cui configuriamo questa istanza sarà diverso poiché il nostro FAB si trova in MainActivity
e il nostro ComposeFragment
è inserito all'interno del contenitore 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 trasformazione del contenitore precedente, 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 da 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 per questo passaggio. Dovresti avere una transizione dal pulsante FAB alla schermata di composizione simile alla seguente:
6. Aggiungi la transizione dell'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é in questa modifica della navigazione non è coinvolto alcun contenitore persistente, possiamo utilizzare una transizione sull'asse Z condiviso per rafforzare la relazione spaziale tra le due schermate e indicare il passaggio a un livello superiore nella gerarchia dell'app.
Prima di aggiungere altro codice, prova a eseguire l'app e tocca 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()
}
}
Aggiungi quindi il seguente snippet di codice al metodo onCreate
in SearchFragment
, che configura le transizioni MaterialSharedAxis
di entrata e ritorno.
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, anziché a ciascuna delle singole visualizzazioni nella 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. Aggiungere la transizione Dissolvenza tra le pagine della cassetta postale
In questo passaggio aggiungeremo una transizione tra caselle di posta diverse. Poiché non vogliamo enfatizzare una relazione spaziale o gerarchica, utilizzeremo una dissolvenza attraverso per eseguire un semplice "scambio" tra elenchi di email.
Prima di aggiungere altro codice, prova a eseguire l'app, toccando il logo Rispondi nella barra delle app in basso e cambiando casella di posta. L'elenco delle email non dovrebbe cambiare durante la transizione.
Per iniziare, trova il metodo navigateToHome
in MainActivity
e aggiungi il seguente snippet di codice prima della chiamata al metodo NavController
navigate
per configurare 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()
}
}
Poi 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 in basso e cambi casella di posta, l'elenco corrente delle email dovrebbe svanire e rimpicciolirsi, mentre il nuovo elenco dovrebbe svanire e ingrandirsi. 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 qualsiasi codice, esegui l'app Rispondi, fai clic su un'email, fai clic sul pulsante FAB "Rispondi" e poi prova a fare clic sul chip contatto di un destinatario. Il chip dovrebbe scomparire immediatamente e una scheda con gli indirizzi email del contatto dovrebbe apparire 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 carta 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à di recipientCardView
e chip
, che attiverà la trasformazione del contenitore 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, questo dovrebbe espandersi in una scheda, mentre se fai clic sulla scheda, questa dovrebbe richiudersi nel 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, consulta le specifiche e la documentazione completa per gli sviluppatori e prova ad aggiungere alcune transizioni Material alla tua app.
Grazie per aver provato Material motion. Speriamo che questo codelab ti sia piaciuto.