Android过渡框架之共享元素过渡
上篇文章介紹了MVVM架構(gòu)的搭建,這次繼續(xù)完善Android All Star項(xiàng)目,實(shí)現(xiàn)Android All Star的搜索功能。使用Android的過渡框架模仿微信的搜索框,實(shí)現(xiàn)兩個(gè)界面之間搜索框平滑切換的效果
先上最終實(shí)現(xiàn)效果圖:
過渡框架簡(jiǎn)介
Android 4.4.2 中引入了 Transition 過渡動(dòng)畫,借助 Android 的過渡框架,只需提供起始布局和結(jié)束布局,即可為界面中的各種view切換添加動(dòng)畫效果,從開發(fā)的角度來講,過渡框架就是實(shí)現(xiàn)了View樹(View Hierarchy)之間的動(dòng)畫切換 。
過渡框架包含以下功能:
- 群組級(jí)動(dòng)畫:將一個(gè)或多個(gè)動(dòng)畫效果應(yīng)用于視圖層次結(jié)構(gòu)中的所有視圖。
- 內(nèi)置動(dòng)畫:對(duì)淡出或移動(dòng)等常見效果使用預(yù)定義動(dòng)畫。
- 資源文件支持:從布局資源文件加載視圖層次結(jié)構(gòu)和內(nèi)置動(dòng)畫。
- 生命周期回調(diào):接收可控制動(dòng)畫和層次結(jié)構(gòu)更改流程的回調(diào)。
作共享元素過渡為過渡框架中的一部分,可以配置fragment過渡期間相應(yīng)視圖如何在兩個(gè)fragment之間移動(dòng)。 例如,您可能希望顯示在fragmenA上ImageView中的圖像在fragmentB變得可見后過渡到fragmentB,效果見下圖:
共享元素過渡的實(shí)現(xiàn)
普通方式實(shí)現(xiàn)共享元素過渡需要三步:
首先,為了將視圖從一個(gè)fragment映射到下一個(gè)fragment,必須為每個(gè)共享元素視圖分配唯一的過渡名稱。 使用ViewCompat.setTransitionName()為每個(gè)fragment布局中的共享元素上設(shè)置過渡名稱,該方式與API級(jí)別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還需要知道每個(gè)共享元素視圖如何從一個(gè)fragment映射到下一個(gè)fragment。 通過調(diào)用FragmentTransaction.addSharedElement()將每個(gè)共享元素添加到FragmentTransaction中,傳入的參數(shù)是共享元素視圖和下一個(gè)fragment中對(duì)應(yīng)共享元素的過渡名稱,如以下示例所示:
val fragment = FragmentB() supportFragmentManager.commit {setCustomAnimations(...)addSharedElement(itemImageView, “hero_image”)replace(R.id.fragment_container, fragment)addToBackStack(null) }要指定共享元素如何從一個(gè)fragment過渡到下一個(gè)fragment,必須在要導(dǎo)航到的fragment中設(shè)置進(jìn)入的過渡效果。 在fragment的onCreate()方法中調(diào)用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的所有子類作為共享元素的過渡。 如果要?jiǎng)?chuàng)建自定義過渡,請(qǐng)參閱創(chuàng)建自定義過渡動(dòng)畫。 在上一個(gè)示例中使用的changeImageTransform是可以使用的可用預(yù)構(gòu)建轉(zhuǎn)換之一。 您可以在Transition類的API參考中找到其他Transition子類。
默認(rèn)情況下,共享元素的進(jìn)入過渡動(dòng)畫也用作共享元素的退出過渡動(dòng)畫。 退出過渡動(dòng)畫確定了FragmentTransaction從堆棧中彈出時(shí)共享元素如何退回上一個(gè)fragment。 如果要指定其他退出過渡動(dòng)畫,則可以在fragment的onCreate()方法中使用Fragment.setSharedElementReturnTransition()進(jìn)行指定。
Navigation實(shí)現(xiàn)共享元素過渡
在兩個(gè)目的地之間共享某個(gè)視圖時(shí),可以使用共享元素過渡來定義從一個(gè)目的地導(dǎo)航到另一個(gè)目的地時(shí)該視圖如何過渡。共享元素過渡是過渡框架的一部分。
注意:使用共享元素過渡時(shí),不能使用動(dòng)畫框架( enterAnim、exitAnim 等),而只能使用過渡框架來設(shè)置進(jìn)入和退出過渡。
共享元素以編程方式提供,而不是通過導(dǎo)航 XML 文件提供。Activity 和 Fragment 目的地各自都有 Navigator.Extras接口的一個(gè)子類,它接受導(dǎo)航的附加選項(xiàng),包括共享元素。您可以在調(diào)用 navigate() 時(shí)傳遞這些 Extras。
Navigation實(shí)現(xiàn)共享元素過度底層也是借助FragmentTransaction實(shí)現(xiàn),Navigation實(shí)現(xiàn)共享元素過渡需要三步:
首先,為每個(gè)共享元素視圖分配一個(gè)唯一的過渡名稱,每個(gè)元素在切換前后的fragment中都需要設(shè)置唯一過渡名稱,如以下示例所示:
//設(shè)置共享元素過渡名稱 ViewCompat.setTransitionName(binding.llSearchBar, "search_enter") ViewCompat.setTransitionName(binding.imgSearch, "search_enter_img") ViewCompat.setTransitionName(binding.txtSearch, "search_enter_txt")借助 FragmentNavigator.Extras類,可以按過渡名稱將共享元素從一個(gè)目的地映射到另一個(gè)目的地,這與使用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(),可以在參數(shù)中設(shè)置過渡動(dòng)畫效果,如以下示例所示:
binding.llSearchBar.setOnClickListener {it.findNavController().navigate(R.id.action_navigation_home_to_searchFragment,null,//切換時(shí)共享元素的動(dòng)畫效果,可選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)}要指定共享元素如何從一個(gè)fragment過渡到下一個(gè)fragment,必須在要導(dǎo)航到的fragment中設(shè)置進(jìn)入的過渡效果。在fragment的onCreate()方法中調(diào)用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>最后實(shí)現(xiàn)的效果如下圖所示:
關(guān)于過渡框架還有很多內(nèi)容可以探索,包括自定義過渡動(dòng)畫、延遲過渡、在RecyclerView中使用共享元素等等,以后有機(jī)會(huì)繼續(xù)研究分享。
項(xiàng)目GitHub地址:android_all_star_app
總結(jié)
以上是生活随笔為你收集整理的Android过渡框架之共享元素过渡的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国牛市
- 下一篇: 服务器sel信息是什么意思,英特尔?服务