Android için Material Motion ile Güzel Geçişler Oluşturma

1. Giriş

Materyal Tasarım, cesur ve güzel dijital ürünler oluşturmaya yönelik bir sistemdir. Ürün ekipleri stil, marka, etkileşim ve hareketi tutarlı bir ilke ve bileşen kümesi altında bir araya getirerek en büyük tasarım potansiyellerini gerçekleştirebilir.

logo_components_color_2x_web_96dp.png

Materyal Bileşenleri (MDC), geliştiricilerin Materyal Tasarım'ı uygulamasına yardımcı olur. Google'da mühendislerden ve kullanıcı deneyimi tasarımcılarından oluşan bir ekip tarafından oluşturulan MDC, onlarca güzel ve işlevsel kullanıcı arayüzü bileşeni içerir. Ayrıca Android, iOS, web ve Flutter.material.io/develop'da kullanılabilir.

Android için Material'ın hareket sistemi nedir?

Android için Materyal hareket sistemi, Materyal Tasarım yönergelerinde açıklandığı gibi kullanıcıların bir uygulamayı anlamasına ve uygulamada gezinmesine yardımcı olabilecek, MDC-Android kitaplığındaki bir dizi geçiş kalıbıdır.

Dört temel Materyal geçiş kalıbı şunlardır:

  • Kapsayıcı Dönüşümü: Kapsayıcı içeren kullanıcı arayüzü öğeleri arasındaki geçişler; bir öğeyi sorunsuz bir şekilde diğerine dönüştürerek iki farklı kullanıcı arayüzü öğesi arasında görünür bir bağlantı oluşturur.
  • Paylaşılan Eksen: Mekansal veya gezinme ilişkisi olan kullanıcı arayüzü öğeleri arasındaki geçişler; öğeler arasındaki ilişkiyi güçlendirmek için x, y veya z ekseninde paylaşılan bir dönüşüm kullanır.
  • Karartma: Birbiriyle güçlü bir ilişkisi olmayan kullanıcı arayüzü öğeleri arasındaki geçişler; ardışık bir belirme ve belirme kullanır.
  • Karart: Ekranın sınırları içinde giren veya çıkan kullanıcı arayüzü öğeleri için kullanılır.

MDC-Android kitaplığı, bu kalıplar için hem AndroidX Geçiş kitaplığı (androidx.transition) hem de Android Geçiş Çerçevesi (android.transition) temel alınarak oluşturulmuş geçiş sınıfları sunar:

AndroidX

  • com.google.android.material.transition paketinde mevcut
  • API Seviye 14 ve sonraki sürümleri destekler
  • Parçaları ve görünümleri destekler ancak etkinlikleri veya pencereleri desteklemez
  • Geriye taşınan hata düzeltmeleri ve API Düzeyleri genelinde tutarlı davranış içerir

Çerçeve

  • com.google.android.material.transition.platform paketinde mevcut
  • API Seviye 21 ve sonraki sürümleri destekler
  • Parçaları, görünümleri, etkinlikleri ve pencereleri destekler
  • Hata düzeltmeleri geri taşınmadı ve API Düzeyleri arasında farklı davranışlara sahip olabilir

Bu codelab'de, AndroidX kitaplığının temelini oluşturan Materyal geçişlerini kullanacaksınız. Bu sayede ağırlıklı olarak Parçalar ve Görünümler'e odaklanacaksınız.

Oluşturacaklarınız

Bu codelab'de, MDC-Android kitaplığındaki geçişleri uygulamanızın görünümünü ve tarzını özelleştirmek için nasıl kullanabileceğinizi göstermek amacıyla, Kotlin kullanarak Reply adlı örnek bir Android e-posta uygulamasına bazı geçişler tasarlayacaksınız.

Yanıtla uygulaması için başlangıç kodu sağlanacak. Ardından, uygulamaya aşağıdaki Material geçişlerini dahil edeceksiniz. Bunları, tamamlanan codelab'in GIF'inde görebilirsiniz:

  • Kapsayıcı Dönüşümü'nün e-posta listesinden e-posta ayrıntıları sayfasına geçiş
  • FAB'dan e-posta oluşturma sayfasına Kapsayıcı Dönüşümü geçişi
  • Arama simgesinden arama görünümü sayfasına paylaşılan Z ekseni geçişi
  • Posta kutusu sayfaları arasında Kararma geçişi
  • Kapsayıcı Dönüşümü'nün e-posta adresi çipinden kart görünümüne geçişi

İstenen iframe'in (youtu.be) alan adı beyaz listeye eklenmemiş.

Gerekenler

  • Android uygulaması geliştirme ve Kotlin ile ilgili temel bilgiler
  • Android Studio (yoksa buradan indirin)
  • Bir Android emülatörü veya cihaz (Android Studio üzerinden kullanılabilir)
  • Örnek kod (sonraki adıma bakın)

Android uygulamaları geliştirme konusundaki deneyim düzeyinizi nasıl değerlendirirsiniz?

Acemi Orta Yeterli

2. Geliştirme ortamınızı ayarlama

Android Studio'yu başlatma

Android Studio'yu açtığınızda "Android Studio'ya Hoş Geldiniz" başlıklı bir pencere gösterilecektir. Ancak, Android Studio'yu ilk kez başlatıyorsanız Android Studio Kurulum Sihirbazı adımlarını varsayılan değerleri kullanarak uygulayın. Bu adımda gerekli dosyaların indirilmesi ve yüklenmesi birkaç dakika sürebilir. Bu nedenle, bir sonraki bölümü yaparken bu dosyayı arka planda çalışır durumda bırakabilirsiniz.

1. seçenek: GitHub'dan başlangıç codelab uygulamasını klonlama

Bu codelab'i GitHub'dan klonlamak için şu komutları çalıştırın:

git clone https://github.com/material-components/material-components-android-motion-codelab.git
cd material-components-android-motion-codelab

2. Seçenek: Başlangıç codelab uygulamasının posta dosyasını indirin

Başlangıç uygulaması material-components-android-motion-codelab-develop dizininde bulunur.

Android Studio'da başlangıç kodunu yükleme

  1. Kurulum sihirbazı tamamlandıktan ve Android Studio'ya Hoş Geldiniz penceresi gösterildikten sonra Mevcut bir Android Studio projesini aç'ı tıklayın.

e3f200327a67a53.png

  1. Örnek kodu yüklediğiniz dizine gidin ve projeyi açmak için örnek dizini seçin.
  2. Android Studio'nun projeyi oluşturup senkronize etmesi için biraz bekleyin. Bunu, Android Studio penceresinin alt kısmındaki etkinlik göstergelerinde de görebilirsiniz.
  1. Bu noktada Android Studio, aşağıda gösterilene benzer Android SDK'sı veya derleme araçları sizde eksik olduğundan bazı derleme hataları oluşturabilir. Bunları yüklemek/güncellemek ve projenizi senkronize etmek için Android Studio'daki talimatları uygulayın. Hâlâ sorun yaşıyorsanız SDK Manager ile araçlarınızı güncelleme kılavuzunu uygulayın.

6e026ae171f5b1eb.png

Proje bağımlılıklarını doğrulama

Projenin MDC-Android kitaplığına bağımlı olması gerekiyor. İndirdiğiniz örnek kodda bu bağımlılığın zaten listelenmiş olması gerekir ancak emin olmak için yapılandırmaya bakalım.

app modülünün build.gradle dosyasına gidin ve dependencies bloğunun MDC-Android'e bir bağımlılık içerdiğinden emin olun:

implementation 'com.google.android.material:material:1.2.0'

Başlangıç uygulamasını çalıştırma

  1. Cihaz seçiminin solundaki derleme yapılandırmasının app olduğundan emin olun.
  2. Uygulamayı geliştirip çalıştırmak için yeşil Çalıştır / Oynat düğmesine basın.

24218d0a6ae25803.png

  1. Select Deployment Target (Dağıtım Hedefi Seçin) penceresinde, kullanılabilir cihazlarınız arasında zaten bir Android cihazınız varsa, 8. Adım'a atlayın. Aksi takdirde, Yeni Sanal Cihaz Oluştur'u tıklayın.
  2. Donanım Seçin ekranında Pixel 3 gibi bir telefon cihazı seçin ve ardından İleri'yi tıklayın.
  3. Sistem Görüntüsü ekranında yeni bir Android sürümünü (tercihen en yüksek API düzeyini) seçin. Yüklü değilse gösterilen İndir bağlantısını tıklayın ve indirme işlemini tamamlayın.
  4. İleri'yi tıklayın.
  5. Android Virtual Device (AVD) ekranında ayarları olduğu gibi bırakın ve Finish'i (Son) tıklayın.
  6. Dağıtım hedefi iletişim kutusundan bir Android cihaz seçin.
  7. Ok'i (Tamam) tıklayın.
  8. Android Studio uygulamayı oluşturur, dağıtır ve hedef cihazda otomatik olarak açar.

Başarıyla gerçekleştirildi. Emülatörünüzde Yanıt'ın ana sayfasının başlangıç kodu çalışıyor olmalıdır. E-posta listesinin yer aldığı Gelen Kutusu gösterilir.

cc73eb0d0f779035.png

İsteğe bağlı: Cihaz animasyonlarını yavaşlatma

Bu codelab'de hızlı ancak gösterişli geçişler yer aldığından, uyguladığınız geçişlerin bazı ince ayrıntılarını inceleyebilmek için cihazın animasyonlarını yavaşlatmanız faydalı olabilir. Bu işlem, adb kabuk komutları veya Hızlı Ayar Kutucuğu ile gerçekleştirilebilir. Cihaz animasyonlarını yavaşlatmaya yönelik bu yöntemlerin, Yanıt uygulamasının dışında da cihazdaki animasyonları etkileyeceğini unutmayın.

1. Yöntem: ADB Kabuk Komutları

Cihazın animasyonlarını 10 kat yavaşlatmak için komut satırından aşağıdaki komutları çalıştırabilirsiniz:

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

Cihazın animasyon hızını tekrar normale sıfırlamak için aşağıdaki komutları çalıştırın:

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

2. Yöntem: Hızlı Ayar Kutucuğu

Alternatif olarak, Hızlı Ayar Kutusunu ayarlamak için daha önce yapmadıysanız önce cihazınızda Geliştirici Ayarları'nı etkinleştirin:

  1. Cihazın "Ayarlar" bölümünü açın uygulama
  2. En alta gidin ve "Emüle edilen cihaz hakkında"yı tıklayın
  3. En alta gidin ve "Derleme numarası"nı hızlıca tıklayın. Geliştirici Ayarları etkinleştirilene kadar

Ardından, cihazın "Ayarlar" bölümünde aşağıdaki işlemleri yapın uygulamasında Hızlı Ayar Kutusunu etkinleştirmek için:

  1. Ekranın üst kısmındaki arama simgesini veya arama çubuğunu tıklayın
  2. "Kutu" yazın arama alanında
  3. "Hızlı ayarlar geliştirici kutuları"nı tıklayın. satır
  4. "Pencere animasyonu ölçeği"ni tıklayın. anahtar

Son olarak, codelab'de sistem bildirim gölgesini ekranın üst kısmından aşağı çekip yavaş ve normal hızdaki animasyonlar arasında geçiş yapmak için c7e3f98200023f6a.png simgesini kullanın.

3. Örnek uygulama kodu hakkında bilgi edinin

Koda bir göz atalım. Birkaç farklı Parça arasında gezinmek için Jetpack Navigation birinin kitaplığını kullanan bir uygulama sağladık. Bu uygulamaların hepsi tek bir etkinlik olan MainActivity'de gerçekleştirilebilir:

  • HomeFragment: E-postaların listesini gösterir
  • EmailFragment: Tek bir tam e-posta gösterir
  • ComposeFragment: Yeni bir e-postanın oluşturulmasına olanak tanır.
  • SearchFragment: Bir arama görünümü görüntüler

İlk olarak, uygulamanın gezinme grafiğinin nasıl oluşturulduğunu anlamak için app -> src -> main -> res -> navigation dizininde navigation_graph.xml uygulamasını açın:

<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>

Yukarıda belirtilen tüm parçaların mevcut olduğuna dikkat edin. Varsayılan başlatma parçası, app:startDestination="@id/homeFragment" aracılığıyla HomeFragment olarak ayarlanır. Parça hedef grafiğinin ve işlemlerin bu XML tanımı, geçişleri bağlarken karşılaşacağınız, oluşturulan Kotlin gezinme kodunu bildirir.

activity_main.xml

Daha sonra, app -> src -> main -> res -> layout dizinindeki activity_main.xml düzenine bakın. Yukarıdaki gezinme grafiğiyle yapılandırılmış NavHostFragment simgesini görürsünüz:

<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"/>

Bu NavHostFragment, ekranı doldurur ve uygulamadaki tam ekran bölüm gezinme değişikliklerini işler. BottomAppBar ve yine activity_main.xml içindeki sabit FloatingActionButton, NavHostFragment tarafından görüntülenen mevcut parçanın üzerine yerleştirilmiştir. Bu nedenle, sağlanan örnek uygulama kodu tarafından parça hedefine bağlı olarak gösterilir veya gizlenir.

Buna ek olarak, activity_main.xml içindeki BottomNavDrawerFragment, farklı e-posta posta kutuları arasında gezinmek için BottomAppBar Yanıtla logosu düğmesiyle koşullu olarak gösterilen bir menü içeren alt çekmecedir.

MainActivity.kt

Son olarak, kullanılan gezinme işleminin bir örneğini görmek için app -> src -> main -> java -> com.materialstudies.reply.ui dizininde MainActivity.kt dosyasını açın. Aşağıdaki gibi görünmesi gereken navigateToSearch() işlevini bulun:

private fun navigateToSearch() {
   val directions = SearchFragmentDirections.actionGlobalSearchFragment()
   findNavController(R.id.nav_host_fragment).navigate(directions)
}

Bu görsel, herhangi bir özel geçiş olmadan arama görünümü sayfasına nasıl gidebileceğinizi gösterir. Bu codelab'de, Yanıt'ın Ana Etkinliği hakkında ayrıntılı bilgi verecek ve uygulamadaki çeşitli gezinme işlemleriyle birlikte çalışan Materyal geçişleri oluşturmaya yönelik dört ana parçayı öğreneceksiniz.

Artık başlangıç kodunu öğrendiğinize göre ilk geçişimizi uygulayalım.

4. E-posta listesinden e-posta ayrıntıları sayfasına kapsayıcı dönüşümü geçişi ekleyin

Başlamak için bir e-postayı tıklayarak geçiş ekleyeceksiniz. Bu gezinme değişikliği için kapsayıcı dönüşüm kalıbı, kapsayıcı içeren kullanıcı arayüzü öğeleri arasındaki geçişler için tasarlandığından çok uygundur. Bu desen, iki kullanıcı arayüzü öğesi arasında görünür bir bağlantı oluşturur.

Herhangi bir kod eklemeden önce, Yanıtla uygulamasını çalıştırmayı ve bir e-postayı tıklamayı deneyin. Sıçramalı kesme sayesinde ekran, geçiş olmadan değiştirilir:

f0e8a92eb2216bce.gif

Aşağıdaki snippet'te gösterildiği gibi email_item_layout.xml içindeki MaterialCardView öğesine bir transitionName özelliği ekleyerek başlayın:

email_item_layout.xml

android:transitionName="@{@string/email_card_transition_name(email.id)}"

Geçiş adı, parametreye sahip bir dize kaynağını alır. EmailFragment listemizdeki her transitionName öğesinin benzersiz olduğundan emin olmak için her e-postanın kimliğini kullanmanız gerekir.

E-posta listesi öğenizin geçiş adını belirlediğinize göre şimdi aynısını e-posta ayrıntıları düzeninde yapalım. fragment_email.xml içinde, MaterialCardView öğesinin transitionName değerini aşağıdaki dize kaynağına ayarlayın:

fragment_email.xml

android:transitionName="@string/email_card_detail_transition_name"

HomeFragment.kt ürününde, başlangıç görünümünüzden (e-posta listesi öğesi) ve bitiş görünümünüzde (e-posta ayrıntıları ekranı) eşleme oluşturmak için onEmailClicked içindeki kodu aşağıdaki snippet ile değiştirin:

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)

Tesisatınızı yapılandırdığınıza göre artık bir konteyner dönüşümü oluşturabilirsiniz. EmailFragment onCreate yönteminde, aşağıdaki snippet'i ekleyerek sharedElementEnterTransition öğesini yeni bir MaterialContainerTransform örneği olarak ayarlayın (com.google.android.material.transition.platform sürümü yerine com.google.android.material.transition sürümünü içe aktarın):

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))
}

Şimdi uygulamayı yeniden çalıştırmayı deneyin.

ed62cedec31da268.gif

Her şey yolunda gitmeye başlıyor. E-posta listesindeki bir e-postayı tıkladığınızda, kapsayıcı dönüştürme işlemi liste öğesini tam ekran ayrıntılar sayfasına genişletmelidir. Ancak geri tuşuna bastığınızda e-postanın tekrar listeye daraltılmadığına dikkat edin. Ayrıca, e-posta listesi geçişin başında hemen kaybolarak gri pencere arka planını gösterir. Henüz işimiz bitmedi.

İade geçişini düzeltmek için HomeFragment.kt uygulamasındaki onViewCreated yöntemine aşağıdaki iki satırı ekleyin:

HomeFragment.kt

postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }

Uygulamayı yeniden çalıştırmayı deneyin. Bir e-postayı açtıktan sonra geri düğmesine basarsanız e-posta tekrar listeye daraltılır. Güzel! Animasyonu geliştirmeye devam edelim.

E-posta listesinin kaybolmasının nedeni, Gezinme Bileşeni'ni kullanarak yeni bir Parça'ya giderken mevcut parçanın hemen kaldırılması ve yerine yeni, gelen Parçamız olmasıdır. E-posta listesinin değiştirildikten sonra bile görünür kalmasını sağlamak için HomeFragment uygulamasına çıkış geçişi ekleyebilirsiniz.

E-posta listesinin çıkış yaparken ve yeniden giriş yaparken yavaşça ölçeklendirilmesini sağlamak için HomeFragment onEmailClicked yöntemine aşağıdaki snippet'i ekleyin:

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()
}

Sonra, MaterialElevationScale geçişinin hiyerarşideki her bir görünüm yerine genel olarak ana ekrana uygulandığından emin olmak için fragment_home.xml içindeki RecyclerView öğesini bir geçiş grubu olarak işaretleyin.

fragment_home.xml

android:transitionGroup="true"

Bu aşamada, tam olarak çalışan bir container dönüşümünüz olmalıdır. Bir e-postayı tıkladığınızda, e-posta listesi çıkartılırken liste öğesi bir ayrıntılar ekranına genişletilir. Geri tuşuna bastığınızda e-posta ayrıntıları ekranı tekrar bir liste öğesi haline getirilirken e-posta listesinde yukarı ölçeklenir.

9df2b39d5a150418.gif

5. E-posta oluşturma sayfasına, FAB'dan Kapsayıcı Dönüşümü geçişi ekleyin

Container dönüşümüyle devam edelim ve Kayan İşlem Düğmesi'nden ComposeFragment öğesine bir geçiş ekleyerek FAB'yi kullanıcı tarafından yazılacak yeni bir e-posta adresine genişletelim. Öncelikle uygulamayı yeniden çalıştırın ve e-posta oluşturma ekranını başlatırken herhangi bir geçiş olmadığını görmek için FAB'yi tıklayın.

d242c9708abd382c.gif

Aynı geçiş sınıfını kullansak da FAB'mız MainActivity içinde yer aldığı ve ComposeFragment öğesimiz MainActivity gezinme ana makine kapsayıcımızın içine yerleştirildiğinden, bu örneği yapılandırma yöntemimiz farklı olacaktır.

ComposeFragment.kt ürününde, aşağıdaki snippet'i onViewCreated yöntemine ekleyin. Bunu yaparken Slide öğesinin androidx.transition sürümünü içe aktardığınızdan emin olun.

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)
}

Önceki container dönüşümümüzü yapılandırmak için kullanılan parametrelere ek olarak startView ve endView burada manuel olarak ayarlanıyor. Hangi görünümlerin dönüştürülmesi gerektiğini Android Transition sistemine bildirmek için transitionName özelliklerini kullanmak yerine gerektiğinde bunları manuel olarak belirtebilirsiniz.

Şimdi uygulamayı yeniden çalıştırın. FAB'nin, oluşturma ekranına dönüştüğünü görürsünüz (bu adımın sonundaki GIF'e bakın).

Önceki adıma benzer şekilde, kaldırılıp ComposeFragment ile değiştirilmesinin ardından kaybolmasını önlemek için HomeFragment öğesine bir geçiş eklemeniz gerekir.

Aşağıdaki snippet'i, NavController navigate çağrısından önce MainActivity içindeki navigateToCompose yöntemine kopyalayın.

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()
   }
}

Bu adımın sonuna geldik! FAB'dan oluşturma ekranına geçişiniz aşağıdaki gibi görünür:

81b68391ac4b0a9.gif

6. Arama simgesinden arama görünümü sayfasına paylaşılan Z ekseni geçişi ekle

Bu adımda, arama simgesinden tam ekran arama görünümüne bir geçiş ekleyeceğiz. Bu gezinme değişikliğine dahil olan kalıcı bir kapsayıcı olmadığından, iki ekran arasındaki uzamsal ilişkiyi güçlendirmek ve uygulamanın hiyerarşisinde bir seviye yukarı hareket ettiğini göstermek için Paylaşılan Z ekseni geçişini kullanabiliriz.

Başka kod eklemeden önce uygulamayı çalıştırmayı ve ekranın sağ alt köşesindeki arama simgesine dokunmayı deneyin. Bunu yaptığınızda, geçiş olmadan arama görünümü ekranı görüntülenir.

499e1a677b4216bb.gif

Başlamak için MainActivity içinde navigateToSearch yöntemini bulun ve geçerli parçanın çıkışını ayarlamak ve MaterialSharedAxis Z Ekseni geçişlerini yeniden girmek için NavController navigate yöntem çağrısından önce aşağıdaki kod snippet'ini ekleyin.

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()
   }
}

Ardından, aşağıdaki kod snippet'ini SearchFragment içindeki onCreate yöntemine ekleyin. Bu yöntem, giriş ve MaterialSharedAxis geçişlerini döndürür.

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()
}

Son olarak, MaterialSharedAxis geçişinin hiyerarşideki görünümlerin her birine değil, tüm arama ekranına uygulandığından emin olmak için fragment_search.xml içindeki LinearLayout öğesini bir geçiş grubu olarak işaretleyin.

fragment_search.xml

android:transitionGroup="true"

İşte bu kadar. Şimdi uygulamayı yeniden çalıştırmayı ve arama simgesine dokunmayı deneyin. Ana sayfa ve arama görünümü ekranları aynı anda Z ekseninde ayrıntılı olarak kararma ve ölçeklenmeli, böylece iki ekran arasında kesintisiz bir efekt sağlanmalıdır.

e5c0b0a130e807db.gif

7. Posta kutusu sayfaları arasında Şeffaflaştırma geçişi ekleme

Bu adımda, farklı posta kutuları arasında bir geçiş ekleyeceğiz. Uzamsal veya hiyerarşik bir ilişkiyi vurgulamak istemediğimizden, basit bir "değiştirme" işlemi yapmak için e-posta listeleri arasında geçiş yapın.

Başka kod eklemeden önce uygulamayı çalıştırmayı, Alt Uygulama Çubuğu'ndaki Yanıtla logosuna dokunmayı ve posta kutularını değiştirmeyi deneyin. E-posta listesi geçiş işlemi olmadan değişir.

2c874c0a4588e8fb.gif

Başlamak için MainActivity içinde navigateToHome yöntemini bulun ve geçerli parçanın çıkış MaterialFadeThrough geçişini ayarlamak için NavController navigate yöntem çağrısından önce aşağıdaki kod snippet'ini ekleyin.

MainActivity.kt

currentNavigationFragment?.apply {
   exitTransition = MaterialFadeThrough().apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
}

Sonra HomeFragment uygulamasını açın. onCreate içinde, parçanın enterTransition öğesini yeni bir MaterialFadeThrough örneğine ayarlayın.

HomeFragment.kt

enterTransition = MaterialFadeThrough().apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}

Uygulamayı yeniden çalıştırın. Alttaki gezinme çekmecesini açıp posta kutularını değiştirdiğinizde, mevcut e-posta listesi kaybolarak genişler ve yeni liste genişler ve genişler. Güzel!

f61dfd58ea7bd3fd.gif

8. E-posta adresi çipinden kart görünümüne Kapsayıcı Dönüşümü geçişi ekleyin

Bu adımda bir çipi pop-up karta dönüştüren bir geçiş ekleyeceksiniz. Kullanıcıya pop-up'ta yapılan işlemin pop-up'ın kaynağı olan çipi etkileyeceğini bildirmek için kapsayıcı dönüşümü kullanılır.

Kod eklemeden önce Yanıtla uygulamasını çalıştırın, bir e-postayı ve "yanıtla" seçeneğini tıklayın FAB'yi seçin ve ardından bir alıcının kişi çipini tıklamayı deneyin. Çip hemen kaybolur ve kişinin e-posta adresini içeren bir kart animasyon olmadan görünür.

6200c682da2382d5.gif

Bu adım için ComposeFragment bölgesinde çalışacaksınız. Alıcı çipleri (varsayılan olarak görünür) ve alıcı kartı (varsayılan olarak görünmez) ComposeFragment düzeninde zaten eklenmiş durumdadır. Alıcı çipi ve bu kart, aralarında kapsayıcı dönüşümü oluşturacağınız iki görünümlerdir.

Başlamak için ComposeFragment uygulamasını açın ve expandChip yöntemini bulun. Bu yöntem, sağlanan chip tıklandığında çağrılır. Aşağıdaki kod snippet'ini, recipientCardView ve chip görünürlüğünü değiştiren satırların üzerine ekleyin. Bu, beginDelayedTransition aracılığıyla kaydedilen kapsayıcı dönüşümünü tetikleyecektir.

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)

Uygulamayı şu anda çalıştırırsanız çipin, alıcının e-posta adreslerinden oluşan bir karta dönüşmesi gerekir. Ardından, kartı tekrar çipin içine daraltacak şekilde iade geçişini yapılandıralım.

ComposeFragment uygulamasındaki collapseChip yönteminde, kartı tekrar çipin içine daraltmak için aşağıdaki kod snippet'ini ekleyin.

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)

Uygulamayı yeniden çalıştırın. Çipi tıkladığınızda çip bir karta genişletilirken kart tıklandığında kart tekrar çipin içine daraltılır. Güzel!

e823b28e2890e05d.gif

9. Hepsi bitti

100 satırdan az Kotlin kodu ve bazı temel XML işaretlemeleri kullanan MDC-Android kitaplığı, mevcut bir uygulamada Materyal Tasarım yönergelerine uyan ve tüm Android cihazlarda tutarlı bir görünüm ve davranışa sahip güzel geçişler oluşturmanıza yardımcı oldu.

454a47ba96017a25.gif

Sonraki adımlar

Materyal hareket sistemi hakkında daha fazla bilgi edinmek için spesifikasyonları ve geliştirici dokümanlarını eksiksiz olarak incelediğinizden emin olun ve uygulamanıza bazı Materyal geçişler eklemeyi deneyin!

Material motion'u denediğiniz için teşekkürler. Bu codelab'den memnun kaldığınızı umuyoruz.

Bu codelab'i makul bir zaman ve çabayla tamamlayabildim

Kesinlikle katılıyorum Katılıyorum Ne memnunum ne değilim Katılmıyorum Kesinlikle katılmıyorum

Gelecekte Materyal hareket sistemini kullanmaya devam etmek istiyorum

Kesinlikle katılıyorum Katılıyorum Ne memnunum ne değilim Katılmıyorum Kesinlikle katılmıyorum