Android过渡框架之共享元素过渡
上篇文章介紹了MVVM架構的搭建,這次繼續完善Android All Star項目,實現Android All Star的搜索功能。使用Android的過渡框架模仿微信的搜索框,實現兩個界面之間搜索框平滑切換的效果
先上最終實現效果圖:
過渡框架簡介
Android 4.4.2 中引入了 Transition 過渡動畫,借助 Android 的過渡框架,只需提供起始布局和結束布局,即可為界面中的各種view切換添加動畫效果,從開發的角度來講,過渡框架就是實現了View樹(View Hierarchy)之間的動畫切換 。
過渡框架包含以下功能:
- 群組級動畫:將一個或多個動畫效果應用于視圖層次結構中的所有視圖。
- 內置動畫:對淡出或移動等常見效果使用預定義動畫。
- 資源文件支持:從布局資源文件加載視圖層次結構和內置動畫。
- 生命周期回調:接收可控制動畫和層次結構更改流程的回調。
作共享元素過渡為過渡框架中的一部分,可以配置fragment過渡期間相應視圖如何在兩個fragment之間移動。 例如,您可能希望顯示在fragmenA上ImageView中的圖像在fragmentB變得可見后過渡到fragmentB,效果見下圖:
共享元素過渡的實現
普通方式實現共享元素過渡需要三步:
首先,為了將視圖從一個fragment映射到下一個fragment,必須為每個共享元素視圖分配唯一的過渡名稱。 使用ViewCompat.setTransitionName()為每個fragment布局中的共享元素上設置過渡名稱,該方式與API級別14及更高版本兼容。 例如,fragmentA和fragmentB中的ImageView的過渡名稱可以如下分配:
class FragmentA : Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {...val itemImageView = view.findViewById<ImageView>(R.id.item_image)ViewCompat.setTransitionName(itemImageView, “item_image”)} }class FragmentB : Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {...val heroImageView = view.findViewById<ImageView>(R.id.hero_image)ViewCompat.setTransitionName(heroImageView, “hero_image”)} }要將共享元素包括在fragment過渡中,FragmentTransaction還需要知道每個共享元素視圖如何從一個fragment映射到下一個fragment。 通過調用FragmentTransaction.addSharedElement()將每個共享元素添加到FragmentTransaction中,傳入的參數是共享元素視圖和下一個fragment中對應共享元素的過渡名稱,如以下示例所示:
val fragment = FragmentB() supportFragmentManager.commit {setCustomAnimations(...)addSharedElement(itemImageView, “hero_image”)replace(R.id.fragment_container, fragment)addToBackStack(null) }要指定共享元素如何從一個fragment過渡到下一個fragment,必須在要導航到的fragment中設置進入的過渡效果。 在fragment的onCreate()方法中調用Fragment.setSharedElementEnterTransition()添加過渡效果,如以下示例所示:
class FragmentB : Fragment() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.shared_image)} }shared_image過渡在xml文件中定義如下:
<!-- res/transition/shared_image.xml --> <transitionSet><changeImageTransform /> </transitionSet>過渡框架支持將Transition的所有子類作為共享元素的過渡。 如果要創建自定義過渡,請參閱創建自定義過渡動畫。 在上一個示例中使用的changeImageTransform是可以使用的可用預構建轉換之一。 您可以在Transition類的API參考中找到其他Transition子類。
默認情況下,共享元素的進入過渡動畫也用作共享元素的退出過渡動畫。 退出過渡動畫確定了FragmentTransaction從堆棧中彈出時共享元素如何退回上一個fragment。 如果要指定其他退出過渡動畫,則可以在fragment的onCreate()方法中使用Fragment.setSharedElementReturnTransition()進行指定。
Navigation實現共享元素過渡
在兩個目的地之間共享某個視圖時,可以使用共享元素過渡來定義從一個目的地導航到另一個目的地時該視圖如何過渡。共享元素過渡是過渡框架的一部分。
注意:使用共享元素過渡時,不能使用動畫框架( enterAnim、exitAnim 等),而只能使用過渡框架來設置進入和退出過渡。
共享元素以編程方式提供,而不是通過導航 XML 文件提供。Activity 和 Fragment 目的地各自都有 Navigator.Extras接口的一個子類,它接受導航的附加選項,包括共享元素。您可以在調用 navigate() 時傳遞這些 Extras。
Navigation實現共享元素過度底層也是借助FragmentTransaction實現,Navigation實現共享元素過渡需要三步:
首先,為每個共享元素視圖分配一個唯一的過渡名稱,每個元素在切換前后的fragment中都需要設置唯一過渡名稱,如以下示例所示:
//設置共享元素過渡名稱 ViewCompat.setTransitionName(binding.llSearchBar, "search_enter") ViewCompat.setTransitionName(binding.imgSearch, "search_enter_img") ViewCompat.setTransitionName(binding.txtSearch, "search_enter_txt")借助 FragmentNavigator.Extras類,可以按過渡名稱將共享元素從一個目的地映射到另一個目的地,這與使用FragmentTransaction.addSharedElement() 類似。隨后可以將 extra 傳遞給 navigate(),如以下示例所示:
val extras = FragmentNavigatorExtras( binding.llSearchBar to "search_start", binding.imgSearch to "search_start_img", binding.txtSearch to "search_start_txt" )將 extra 傳遞給 navigate(),可以在參數中設置過渡動畫效果,如以下示例所示:
binding.llSearchBar.setOnClickListener {it.findNavController().navigate(R.id.action_navigation_home_to_searchFragment,null,//切換時共享元素的動畫效果,可選NavOptions.Builder().setEnterAnim(R.animator.nav_default_enter_anim).setExitAnim(R.animator.nav_default_exit_anim).setPopEnterAnim(R.animator.nav_default_pop_enter_anim).setPopExitAnim(R.animator.nav_default_pop_exit_anim).build(),extras)}要指定共享元素如何從一個fragment過渡到下一個fragment,必須在要導航到的fragment中設置進入的過渡效果。在fragment的onCreate()方法中調用Fragment.setSharedElementEnterTransition()添加過渡效果,如以下示例所示:
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.slide)sharedElementReturnTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.slide)}slide過渡在xml文件中定義如下:
<?xml version="1.0" encoding="utf-8"?><!-- res/transition/slide_right.xml --> <transitionSet><changeScroll /><changeBounds /> </transitionSet>最后實現的效果如下圖所示:
關于過渡框架還有很多內容可以探索,包括自定義過渡動畫、延遲過渡、在RecyclerView中使用共享元素等等,以后有機會繼續研究分享。
項目GitHub地址:android_all_star_app
總結
以上是生活随笔為你收集整理的Android过渡框架之共享元素过渡的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国牛市
- 下一篇: Android 适配器 自定义