
Di Internet, ada banyak template animasi yang menarik dengan antarmuka pengguna yang indah dari aplikasi seluler, tetapi tidak ada banyak contoh dengan penerapan antarmuka ini. Terlepas dari banyaknya beragam kerangka kerja dan alat bawaan di Android SDK, seringkali tidak mudah bagi pengembang pemula untuk mengimplementasikan antarmuka pengguna yang indah, termasuk dengan templat yang sudah jadi.
Pada artikel ini, kami akan mencoba mengimplementasikan antarmuka pengguna yang dikembangkan oleh desainer Ivan Parfyonov untuk studio PLATES.
Pertama, buat dua fragmen: 
RecyclerFragment dan 
DetailsFragment .
Kerangka kerja Android Transition?
Kerangka kerja Android Transition bekerja dengan baik, tetapi ada beberapa nuansa. Pertama, kami ingin semuanya berfungsi untuk kami setidaknya di API 19, dan kedua, kami perlu menghidupkan beberapa elemen pengguna pada saat yang sama dan beberapa dari mereka hadir hanya dalam satu fragmen. Oleh karena itu, kami menerapkan animasi elemen transisi (transisi elemen bersama) secara manual menggunakan 
ViewPropertyAnimator .
Semua beres
- Kami menghitung koordinat akhir dari elemen yang dipilih dari daftar (koordinatnya di DerailsFragment), daftarnya adalahRecyclerView;
- Kami menyimpan koordinat saat ini (koordinat dalam RecyclerFragment) dan meneruskannya keDetailsFragment(ini diperlukan untuk animasi terbalik dengan API <21);
- Buat salinan item yang dipilih dari daftar;
- Kami membuat elemen yang dipilih tidak terlihat (bukan salinan, tetapi elemen itu sendiri);
- Tambahkan salinan yang dibuat pada langkah 3 ke tata letak root dari fragmen induk, dalam kasus kami ini adalah RecyclerFragment;
- Kami memulai animasi elemen antarmuka yang tersisa dan memindahkan salinan yang dibuat ke koordinat akhir dari langkah 1;
- Ketika animasi selesai, buat transaksi dan tampilkan DetailsFragment;
- Kami memulai animasi elemen antarmuka di DetailsFragment.
Animasi Elemen UI
Untuk menghidupkan 
Toolbar kami akan membuat 
View tambahan di 
RecyclerFragment dan menempatkannya di belakang layar di bagian atas. 
View ini akan dianimasikan dalam wadah 
Toolbar di 
DetailsFragment (warna biru pada gif) menggunakan 
ViewPropertyAnimator .
 <View android:id="@+id/details_toolbar_helper" android:layout_width="wrap_content" android:layout_height="@dimen/details_toolbar_container_height" android:background="@color/colorPrimary" app:layout_constraintTop_toTopOf="parent"/>  
BottomNavigationView dan 
RecyclerView juga diimplementasikan menggunakan 
ViewPropertyAnimator , tidak ada yang rumit (mengubah transparansi dan memindahkan).
Sedikit dari kerangka Transisi
Dengan kata-kata sederhana, maka kerangka transisi android, ketika mulai menggerakkan elemen transisi, membuat salinan konten elemen transisi ini (seperti layar cetak), membuat ImageView dari salinan ini, kemudian menambahkan gambar ini ke lapisan overlay tambahan di lapisan overlay fragmen yang disebut dan memulai animasi.
Kerangka transisi android tidak cukup cocok untuk kita, karena ketika animasi elemen transisi dimulai, maka semua elemen antarmuka pengguna lain dalam fragmen dihancurkan dan kami tidak dapat menghidupkannya. Yaitu Ketika kita mengklik item daftar di 
RecyclerFragment untuk membuka 
DetailsFragment dan memulai animasi transisi, maka semua elemen antarmuka lainnya di 
RecyclerFragment dihancurkan tanpa animasi.
Untuk mendapatkan hasil yang diinginkan, kami akan secara manual membuat salinan elemen yang dipilih dari daftar, menambahkannya ke lapisan overlay dan kemudian menghidupkan. Tapi di sini muncul masalah kecil, dokumentasi untuk metode 
ViewGroupOverlay add(view: View) mengatakan:
Jika tampilan memiliki orang tua, tampilan akan dihapus dari orang tua itu sebelum ditambahkan ke overlay.
Tetapi untuk 
RecyclerView ini tidak berfungsi, item yang dipilih tidak dihapus dari 
RecyclerView setelah ditambahkan ke lapisan overlay.
Inilah yang terjadi ketika kami menambahkan item yang dipilih ke lapisan overlay:
Dan kami membutuhkan ini:
Oleh karena itu, kami tidak akan menggunakan lapisan overlay, dan kami akan segera menambahkan salinannya ke tata letak root. Buat salinan konten dari item yang dipilih, tambahkan ke 
ImageView dan atur koordinat:
 fun View.copyViewImage(): View { val copy = ImageView(context) val bitmap = drawToBitmap() copy.setImageBitmap(bitmap) //  pre-Lollipop   ,   card view  ,      card view return (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CardView(context).apply { cardElevation = resources.getDimension(R.dimen.card_elevation) radius = resources.getDimension(R.dimen.card_corner_radius) addView(copy) } } else { copy }).apply { layoutParams = this@copyViewImage.layoutParams layoutParams.height = this@copyViewImage.height layoutParams.width = this@copyViewImage.width x = this@copyViewImage.x y = this@copyViewImage.y } } 
Mengapa membuat salinan jika Anda hanya bisa menghidupkan barang yang dipilih langsung dari daftar?Karena 
RecyclerView sendiri juga akan dianimasikan dan, karenanya, semua elemennya, termasuk yang dipilih, yang ingin kami animasikan secara terpisah.
Setelah itu, tambahkan salinan ke markup root dan mulai animasinya.
 override fun onClick(view: View) { val fragmentTransaction = initFragmentTransaction(view) val copy = view.createCopyView() root.addView(copy) view.visibility = View.INVISIBLE startAnimation(copy, fragmentTransaction) } 
Dan inilah yang kami dapatkan:
Garis finish
Animasi gif di atas terjadi di 
RecyclerFragment , dan setelah selesai kita perlu menampilkan 
DetailsFragment .
 .withEndAction { fragmentTransaction?.commitAllowingStateLoss() } 
Mengapa kami menggunakan commitAllowingStateLoss ?Jika Anda tidak menggunakannya dan pada saat animasi akan ada, misalnya, perubahan orientasi layar, maka kita akan mendapatkan 
IllegalStateExeption . 
Ini ditulis dengan baik tentang itu.
Selanjutnya, kita mulai animasi elemen antarmuka pengguna yang diperlukan di 
DetailsFragment .
Jalankan semuanya bersama-sama
Tidak persis sama dengan aslinya, tetapi tampilannya mirip.
Contohnya
Kode sumber tersedia di 
GitHub , dan artikel ini juga tersedia dalam 
bahasa Inggris .
Terima kasih atas perhatian anda!