Framework transisi Android memungkinkan Anda menganimasikan semua jenis gerakan UI Anda dengan menyediakan tata letak awal dan akhir. Anda dapat memilih jenis animasi yang diinginkan, seperti memudarkan tampilan masuk atau keluar, atau untuk mengubah ukuran tampilan—dan framework transisi menentukan cara menganimasikan dari tata letak awal hingga tata letak akhir.
Framework transisi mencakup fitur berikut:
- Animasi tingkat grup: menerapkan efek animasi ke semua tampilan dalam hierarki tampilan.
- Animasi bawaan: gunakan animasi yang telah ditentukan untuk efek umum seperti memudar atau bergerak.
- Dukungan file resource: memuat hierarki tampilan dan animasi bawaan dari file resource tata letak.
- Callback siklus proses: menerima callback yang memberikan kontrol atas animasi dan hierarki proses perubahan.
Untuk kode contoh yang menganimasikan perubahan tata letak, lihat BasicTransition.
Proses dasar untuk memberi animasi antara dua tata letak adalah sebagai berikut:
- Buat objek
Scene
untuk {i>layout<i} awal dan akhir. Namun, scene tata letak awal sering kali ditentukan secara otomatis dari tata letak saat ini. - Membuat
Transition
untuk menentukan jenis animasi yang Anda inginkan. - Telepon
TransitionManager.go()
, dan sistem akan menjalankan animasi untuk menukar tata letak.
Diagram pada gambar 1 mengilustrasikan hubungan antara tata letak, adegan, transisi, dan animasi akhir.
Gambar 1. Ilustrasi dasar dari bagaimana kerangka kerja transisi membuat animasi.
Membuat scene
Scene menyimpan status hierarki tampilan, termasuk semua tampilan dan tampilan nilai properti. Framework transisi dapat menjalankan animasi antara dan adegan akhir.
Anda dapat membuat scene dari tata letak file resource atau dari grup tampilan dalam kode Anda. Namun, awal transisi Anda sering kali ditentukan secara otomatis dari UI saat ini.
Scene juga dapat menentukan tindakannya sendiri yang berjalan saat Anda membuat perubahan scene. Fitur ini berguna untuk membersihkan setelan tampilan setelah Anda untuk beralih ke suatu adegan.
Membuat scene dari resource tata letak
Anda dapat membuat instance Scene
langsung dari resource tata letak
. Gunakan teknik ini saat sebagian besar hierarki tampilan dalam file bersifat statis.
Adegan yang dihasilkan merepresentasikan status hierarki tampilan pada saat Anda
membuat instance Scene
. Jika Anda mengubah hierarki tampilan,
membuat ulang adegan. Framework ini membuat scene dari seluruh tampilan
hierarki pada {i>file<i}. Anda tidak dapat membuat scene dari bagian file tata letak.
Untuk membuat instance Scene
dari file resource tata letak, ambil
root scene dari tata letak Anda sebagai
ViewGroup
. Kemudian, panggil metode
Scene.getSceneForLayout()
dengan root scene dan ID resource dari file tata letak yang
berisi hierarki tampilan untuk adegan.
Menentukan tata letak untuk scene
Cuplikan kode di sisa bagian ini menunjukkan cara membuat dua
adegan berbeda dengan elemen {i>
root<i} adegan yang sama. Cuplikan ini juga menunjukkan
Anda dapat memuat beberapa objek Scene
yang tidak terkait tanpa menyiratkan bahwa objek tersebut
saling terkait.
Contoh ini terdiri dari definisi tata letak berikut:
- Tata letak utama aktivitas dengan label teks dan turunan
FrameLayout
ConstraintLayout
untuk adegan pertama dengan dua kolom teks.ConstraintLayout
untuk scene kedua dengan dua kolom teks yang sama di urutan yang berbeda.
Contoh ini didesain agar semua animasi terjadi dalam turunan tata letak utama untuk aktivitas. Label teks di tata letak utama tetap statis.
Tata letak utama untuk aktivitas ini didefinisikan sebagai berikut:
res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/master_layout"> <TextView android:id="@+id/title" ... android:text="Title"/> <FrameLayout android:id="@+id/scene_root"> <include layout="@layout/a_scene" /> </FrameLayout> </LinearLayout>
Definisi tata letak ini berisi kolom teks dan turunan FrameLayout
untuk
root scene. Tata letak untuk scene pertama disertakan dalam file tata letak utama.
Hal ini memungkinkan aplikasi menampilkannya sebagai bagian dari antarmuka pengguna awal dan juga memuat
ke dalam scene, karena kerangka kerja hanya dapat memuat seluruh file tata letak ke dalam
latar depan.
Tata letak untuk scene pertama didefinisikan sebagai berikut:
res/layout/a_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
Tata letak untuk adegan kedua berisi dua bidang teks yang sama—dengan ID yang sama—ditempatkan dalam urutan yang berbeda. Hal ini didefinisikan sebagai berikut:
res/layout/another_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
Membuat scene dari tata letak
Setelah membuat definisi untuk dua tata letak batasan, Anda bisa mendapatkan untuk setiap elemen. Hal ini memungkinkan Anda beralih antara dua UI konfigurasi standar. Untuk mendapatkan scene, Anda memerlukan referensi ke root scene dan tata letak ID resource.
Cuplikan kode berikut menunjukkan cara mendapatkan referensi ke root scene dan
buat dua objek Scene
dari file tata letak:
Kotlin
val sceneRoot: ViewGroup = findViewById(R.id.scene_root) val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this) val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)
Java
Scene aScene; Scene anotherScene; // Create the scene root for the scenes in this app. sceneRoot = (ViewGroup) findViewById(R.id.scene_root); // Create the scenes. aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this); anotherScene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);
Di aplikasi, kini ada dua objek Scene
berdasarkan tampilan
hierarki. Kedua scene menggunakan root scene yang ditentukan oleh
Elemen FrameLayout
di res/layout/activity_main.xml
.
Membuat scene dalam kode Anda
Anda juga dapat membuat instance Scene
dalam kode dari
Objek ViewGroup
. Gunakan teknik ini saat Anda mengubah hierarki tampilan
langsung di dalam kode Anda atau saat
Anda membuatnya secara dinamis.
Untuk membuat scene dari hierarki tampilan dalam kode Anda, gunakan metode
Scene(sceneRoot, viewHierarchy)
. Memanggil konstruktor ini sama dengan memanggil metode
Scene.getSceneForLayout()
fungsi bila Anda sudah meng-inflate file tata letak.
Cuplikan kode berikut menunjukkan cara membuat Scene
dari elemen root scene dan hierarki tampilan untuk scene dalam
kode Anda:
Kotlin
val sceneRoot = someLayoutElement as ViewGroup val viewHierarchy = someOtherLayoutElement as ViewGroup val scene: Scene = Scene(sceneRoot, viewHierarchy)
Java
Scene mScene; // Obtain the scene root element. sceneRoot = (ViewGroup) someLayoutElement; // Obtain the view hierarchy to add as a child of // the scene root when this scene is entered. viewHierarchy = (ViewGroup) someOtherLayoutElement; // Create a scene. mScene = new Scene(sceneRoot, mViewHierarchy);
Membuat tindakan scene
Framework ini memungkinkan Anda menentukan tindakan scene kustom yang akan dijalankan sistem saat memasuki atau keluar dari sebuah adegan. Umumnya, menentukan tindakan scene kustom tidak diperlukan, karena kerangka kerja menganimasikan perubahan antar adegan secara otomatis.
Tindakan scene berguna untuk menangani kasus berikut:
- Untuk menganimasikan tampilan yang tidak berada dalam hierarki yang sama. Anda dapat menganimasikan tampilan adegan awal dan akhir menggunakan tindakan adegan keluar dan masuk.
- Untuk menganimasikan tampilan yang tidak dapat dianimasikan secara otomatis oleh framework transisi,
seperti objek
ListView
. Untuk selengkapnya informasi, lihat bagian tentang batasan.
Untuk menyediakan tindakan scene kustom, tentukan tindakan Anda sebagai
objek Runnable
dan teruskan ke
Scene.setExitAction()
atau Scene.setEnterAction()
fungsi-fungsi lainnya. Framework ini memanggil fungsi setExitAction()
di awal
scene sebelum menjalankan animasi transisi dan setEnterAction()
pada scene akhir setelah menjalankan animasi transisi.
Menerapkan transisi
Framework transisi merepresentasikan gaya animasi antar-adegan dengan
Objek Transition
. Anda dapat membuat instance Transition
menggunakan
subclass, seperti
AutoTransition
dan
Fade
, atau
menentukan transisi Anda sendiri.
Kemudian, Anda dapat menjalankan
animasi antar-adegan dengan meneruskan Scene
akhir
dan Transition
untuk
TransitionManager.go()
.
Siklus proses transisi mirip dengan siklus proses aktivitas, dan mewakili status transisi bahwa {i>framework<i} memantau antara {i>start<i} dan penyelesaian animasi. Saat berada dalam status siklus proses yang penting, framework memanggil fungsi callback yang dapat Anda terapkan untuk menyesuaikan antarmuka pengguna di fase-fase transisi yang berbeda.
Membuat transisi
Bagian sebelumnya menunjukkan cara membuat scene yang mewakili status
hierarki tampilan yang berbeda. Setelah Anda menentukan adegan
awal dan akhir yang
ingin beralih antara, membuat objek Transition
yang mendefinisikan animasi.
Framework ini memungkinkan Anda menentukan transisi bawaan dalam file resource
dan meng-inflate-nya dalam kode Anda atau membuat instance transisi bawaan
langsung di dalam kode Anda.
Tabel 1. Jenis transisi bawaan.
Class | Tag | Efek |
---|---|---|
AutoTransition |
<autoTransition/> |
Transisi default. Memudar, menggerakkan dan mengubah ukuran, dan memudar dalam tampilan, dalam urutan tersebut. |
ChangeBounds |
<changeBounds/> |
Memindahkan dan mengubah ukuran tampilan. |
ChangeClipBounds |
<changeClipBounds/> |
Mengambil View.getClipBounds() sebelum dan sesudah adegan
dan menganimasikan perubahan tersebut selama transisi. |
ChangeImageTransform |
<changeImageTransform/> |
Mengambil matriks ImageView sebelum dan setelah scene
berubah dan menganimasikannya selama transisi. |
ChangeScroll |
<changeScroll/> |
Menangkap properti scroll target sebelum dan setelah scene mengubah dan menganimasikan setiap perubahan. |
ChangeTransform |
<changeTransform/> |
Merekam skala dan rotasi tampilan sebelum dan setelah perubahan adegan dan menganimasikan perubahan tersebut selama transisi. |
Explode |
<explode/> |
Melacak perubahan pada visibilitas target penayangan di awal dan akhir dan memindahkan tampilan masuk atau keluar dari tepi adegan. |
Fade |
<fade/> |
fade_in memperjelas tampilan.fade_out memudarkan tampilan.fade_in_out (default) melakukan fade_out diikuti dengan
fade_in .
|
Slide |
<slide/> |
Melacak perubahan pada visibilitas target penayangan di awal dan akhir adegan dan memindahkan tampilan masuk atau keluar dari salah satu tepi adegan. |
Membuat instance transisi dari file resource
Teknik ini memungkinkan Anda mengubah definisi transisi tanpa mengubah kode aktivitas Anda. Teknik ini juga berguna untuk memisahkan definisi transisi dari kode aplikasi, seperti yang ditunjukkan pada bagian tentang menentukan beberapa transisi.
Untuk menentukan transisi bawaan dalam file resource, ikuti langkah-langkah berikut:
- Tambahkan direktori
res/transition/
ke project Anda. - Buat file resource XML baru di dalam direktori ini.
- Tambahkan node XML untuk salah satu transisi bawaan.
Misalnya, file resource berikut menentukan transisi Fade
:
res/transition/fade_transition.xml
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
Cuplikan kode berikut menunjukkan cara meng-inflate instance Transition
di dalam
aktivitas Anda dari file resource:
Kotlin
var fadeTransition: Transition = TransitionInflater.from(this) .inflateTransition(R.transition.fade_transition)
Java
Transition fadeTransition = TransitionInflater.from(this). inflateTransition(R.transition.fade_transition);
Membuat instance transisi dalam kode Anda
Teknik ini berguna untuk membuat objek transisi secara dinamis jika Anda memodifikasi antarmuka pengguna dalam kode Anda dan membuat transisi bawaan yang sederhana instance dengan sedikit atau tanpa parameter.
Untuk membuat instance transisi bawaan, panggil salah satu instance publik
konstruktor di subclass dari class Transition
. Misalnya,
cuplikan kode berikut membuat instance transisi Fade
:
Kotlin
var fadeTransition: Transition = Fade()
Java
Transition fadeTransition = new Fade();
Menerapkan transisi
Anda biasanya menerapkan transisi untuk beralih di antara hierarki tampilan yang berbeda dalam terhadap peristiwa, seperti tindakan pengguna. Misalnya, pertimbangkan aplikasi penelusuran: saat pengguna memasukkan istilah penelusuran dan mengetuk tombol penelusuran, aplikasi akan berubah ke adegan yang merepresentasikan tata letak hasil saat menerapkan transisi yang memperjelas tombol pencarian dan memperjelas hasil pencarian.
Untuk membuat perubahan adegan saat menerapkan transisi sebagai respons terhadap peristiwa di
aktivitas Anda, panggil fungsi class TransitionManager.go()
dengan akhiran
dan instance transisi yang akan digunakan untuk animasi, seperti ditunjukkan dalam
cuplikan berikut:
Kotlin
TransitionManager.go(endingScene, fadeTransition)
Java
TransitionManager.go(endingScene, fadeTransition);
Framework mengubah hierarki tampilan di dalam root scene dengan tampilan dari scene akhir saat menjalankan animasi yang ditentukan oleh atribut instance transisi. Adegan awal adalah adegan akhir dari adegan terakhir transisi. Jika tidak ada transisi sebelumnya, scene awal akan ditentukan secara otomatis dari status antarmuka pengguna saat ini.
Jika Anda tidak menentukan sebuah instance transisi, pengelola transisi dapat menerapkan sebuah
transisi otomatis yang melakukan sesuatu
yang wajar untuk sebagian besar situasi. Sebagai
informasi selengkapnya, lihat referensi API untuk
TransitionManager
.
Memilih tampilan target khusus
Framework ini menerapkan transisi ke semua tampilan pada scene awal dan akhir
secara {i>default<i}. Dalam beberapa kasus, Anda mungkin hanya ingin menerapkan animasi ke sebuah {i>subset<i}
yang sama dalam satu adegan. Kerangka kerja ini memungkinkan Anda memilih tampilan tertentu yang ingin
beranimasi. Misalnya, kerangka kerja tidak mendukung animasi perubahan pada
ListView
, jadi jangan coba menganimasikannya selama transisi.
Setiap tampilan yang dianimasikan oleh transisi disebut target. Anda hanya dapat memilih target yang merupakan bagian dari hierarki tampilan yang terkait dengan scene.
Untuk menghapus satu atau beberapa tampilan dari daftar target, panggil metode
removeTarget()
sebelum memulai transisi. Untuk menambahkan hanya tampilan yang Anda tentukan ke
daftar target, panggil metode
addTarget()
. Untuk informasi selengkapnya, lihat referensi API untuk
Class Transition
.
Menentukan beberapa transisi
Untuk mendapatkan dampak maksimal dari animasi, cocokkan dengan jenis perubahan yang muncul di antara adegan. Misalnya, jika Anda menghapus beberapa tampilan dan menambahkan yang lain antar adegan, animasi memudar atau pudar yang menunjukkan bahwa beberapa tampilan tidak lagi tersedia. Jika Anda memindahkan tampilan ke titik yang berbeda di layar, lebih baik menganimasikan gerakannya sehingga pengguna memperhatikan lokasi baru dari tampilan.
Anda tidak harus memilih hanya satu animasi, karena framework transisi memungkinkan Anda menggabungkan efek animasi dalam kumpulan transisi yang berisi sekelompok transisi bawaan atau khusus individual.
Untuk mendefinisikan set transisi dari kumpulan transisi dalam XML, buat sebuah elemen
file resource di direktori res/transitions/
dan cantumkan transisi pada
elemen TransitionSet
. Misalnya, cuplikan berikut menunjukkan cara
menentukan kumpulan transisi yang memiliki perilaku yang sama seperti AutoTransition
:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"> <fade android:fadingMode="fade_out" /> <changeBounds /> <fade android:fadingMode="fade_in" /> </transitionSet>
Untuk meng-inflate transisi yang ditetapkan menjadi
Objek TransitionSet
di
kode Anda, panggil metode
TransitionInflater.from()
dalam aktivitas Anda. Class TransitionSet
diperluas dari class
Transition
, sehingga Anda dapat menggunakannya dengan pengelola transisi seperti halnya
instance Transition
lainnya.
Menerapkan transisi tanpa scene
Mengubah hierarki tampilan bukan satu-satunya cara untuk mengubah antarmuka pengguna Anda. Anda bisa juga membuat perubahan dengan menambah, memodifikasi, dan menghapus tampilan turunan di dalam saat ini.
Misalnya, Anda dapat menerapkan interaksi penelusuran dengan
dalam satu tata letak. Mulai dengan tata letak yang menunjukkan kolom entri penelusuran dan penelusuran
ikon. Untuk mengubah antarmuka pengguna agar dapat menampilkan hasil, hapus tombol penelusuran
saat pengguna mengetuknya dengan memanggil
ViewGroup.removeView()
fungsi dan menambahkan hasil
pencarian dengan memanggil
ViewGroup.addView()
.
Anda dapat menggunakan pendekatan ini jika alternatifnya adalah memiliki dua hierarki yang nyaris identik. Daripada membuat dan mengelola dua file tata letak terpisah untuk perbedaan kecil di antarmuka pengguna, Anda dapat menggunakan satu file tata letak berisi hierarki tampilan yang Anda modifikasi dalam kode.
Jika Anda membuat perubahan dalam hierarki tampilan saat ini dengan cara ini, Anda tidak perlu membuat suasana. Sebagai gantinya, Anda dapat membuat dan menerapkan transisi antara dua status hierarki tampilan menggunakan transisi tertunda. Fitur ini framework transisi dimulai dengan status hierarki tampilan saat ini, kumpulan data perubahan yang Anda buat pada tampilannya, dan menerapkan transisi yang menganimasikan berubah ketika sistem menggambar ulang antarmuka pengguna.
Untuk membuat transisi yang tertunda dalam hierarki tampilan tunggal, ikuti langkah-langkah berikut langkah:
- Bila peristiwa yang memicu transisi terjadi, panggil metode
TransitionManager.beginDelayedTransition()
, memberikan tampilan induk dari semua tampilan yang ingin Anda ubah dan transisi yang digunakan. Kerangka kerja ini menyimpan status tampilan turunan dan nilai propertinya. - Buat perubahan pada tampilan turunan seperti yang diminta oleh kasus penggunaan Anda. Kerangka kerja mencatat perubahan yang Anda buat pada tampilan turunan dan propertinya.
- Ketika sistem menggambar ulang antarmuka pengguna sesuai dengan perubahan Anda, framework menganimasikan perubahan antara status asli dan status baru.
Contoh berikut menunjukkan cara menganimasikan penambahan tampilan teks ke tampilan menggunakan transisi yang tertunda. Cuplikan pertama menunjukkan tata letak file definisi:
res/layout/activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/inputText" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> ... </androidx.constraintlayout.widget.ConstraintLayout>
Cuplikan berikutnya menunjukkan kode yang menganimasi penambahan tampilan teks:
MainActivity
Kotlin
setContentView(R.layout.activity_main) val labelText = TextView(this).apply { text = "Label" id = R.id.text } val rootView: ViewGroup = findViewById(R.id.mainLayout) val mFade: Fade = Fade(Fade.IN) TransitionManager.beginDelayedTransition(rootView, mFade) rootView.addView(labelText)
Java
private TextView labelText; private Fade mFade; private ViewGroup rootView; ... // Load the layout. setContentView(R.layout.activity_main); ... // Create a new TextView and set some View properties. labelText = new TextView(this); labelText.setText("Label"); labelText.setId(R.id.text); // Get the root view and create a transition. rootView = (ViewGroup) findViewById(R.id.mainLayout); mFade = new Fade(Fade.IN); // Start recording changes to the view hierarchy. TransitionManager.beginDelayedTransition(rootView, mFade); // Add the new TextView to the view hierarchy. rootView.addView(labelText); // When the system redraws the screen to show this update, // the framework animates the addition as a fade in.
Mendefinisikan callback siklus proses transisi
Siklus proses transisi mirip dengan siklus proses aktivitas. Model tersebut mewakili
status transisi yang dipantau framework selama periode antar-panggilan
ke fungsi TransitionManager.go()
dan penyelesaian
animasinya. Saat memasuki status siklus proses yang penting, framework memanggil callback
ditentukan oleh TransitionListener
dalam antarmuka berbasis web
yang sederhana.
Callback siklus proses transisi berguna, misalnya, untuk menyalin tampilan
nilai properti dari hierarki tampilan awal hingga hierarki tampilan akhir
selama perubahan adegan. Anda tidak bisa begitu saja menyalin nilai dari tampilan awal ke
tampilan dalam hierarki tampilan akhir, karena hierarki tampilan akhir tidak
digelembungkan hingga transisi selesai. Sebaliknya, Anda perlu menyimpan nilai
di variabel, lalu menyalinnya ke hierarki tampilan akhir saat framework
telah menyelesaikan transisi. Agar diberi tahu saat transisi selesai,
menerapkan
TransitionListener.onTransitionEnd()
dalam aktivitas Anda.
Untuk informasi selengkapnya, lihat referensi API untuk
TransitionListener
.
Batasan
Bagian ini mencantumkan beberapa batasan framework transisi umum:
- Animasi yang diterapkan ke
SurfaceView
mungkin tidak muncul dengan benar. InstanceSurfaceView
diupdate dari thread non-UI, sehingga pembaruan mungkin tidak sinkron dengan animasi tampilan lain. - Beberapa jenis transisi tertentu mungkin tidak menghasilkan efek animasi yang diinginkan
saat diterapkan ke
TextureView
. - Class yang memperluas
AdapterView
, sepertiListView
, mengelola pandangan turunan mereka dengan cara yang tidak sesuai dengan kerangka kerja transisi. Jika Anda mencoba menganimasikan tampilan berdasarkanAdapterView
, layar perangkat mungkin berhenti merespons. - Jika Anda mencoba mengubah ukuran
TextView
dengan animasi, teks muncul ke lokasi baru sebelum objek sepenuhnya diubah ukurannya. Untuk menghindari masalah ini, jangan animasikan perubahan ukuran tampilan yang berisi teks.