How to implement shared transition element from RecyclerView item to Fragment with Android Navigation Component?

前端 未结 5 1556
梦如初夏
梦如初夏 2020-12-30 06:38

I have a pretty straightforward case. I want to implement shared element transition between an item in recyclerView and fragment. I\'m using androi

5条回答
  •  庸人自扰
    2020-12-30 07:09

    I have managed return transitions to work.

    Actually this is not a bug in Android and not a problem with setReorderingAllowed = true. What happens here is the original fragment (to which we return) trying to start transition before its views/data are settled up.

    To fix this we have to use postponeEnterTransition() and startPostponedEnterTransition().

    For example: Original fragment:

    class FragmentOne : Fragment(R.layout.f1) {
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            postponeEnterTransition()
    
            val items = listOf("one", "two", "three", "four", "five")
                .zip(listOf(Color.RED, Color.GRAY, Color.GREEN, Color.BLUE, Color.YELLOW))
                .map { Item(it.first, it.second) }
    
            val rv = view.findViewById(R.id.rvItems)
            rv.adapter = ItemsAdapter(items) { item, view -> navigateOn(item, view) }
    
            view.doOnPreDraw { startPostponedEnterTransition() }
        }
    
        private fun navigateOn(item: Item, view: View) {
            val extras = FragmentNavigatorExtras(view to "yura")
            findNavController().navigate(FragmentOneDirections.toTwo(item), extras)
        }
    }
    

    Next fragment:

    class FragmentTwo : Fragment(R.layout.f2) {
    
        val item: Item by lazy { arguments?.getSerializable("item") as Item }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            sharedElementEnterTransition =
                TransitionInflater.from(context).inflateTransition(android.R.transition.move)
    
            val tv = view.findViewById(R.id.tvItemId)
            with(tv) {
                text = item.id
                transitionName = "yura"
                setBackgroundColor(item.color)
            }
        }
    
    }
    

    For more details and deeper explanation see: https://issuetracker.google.com/issues/118475573 and https://chris.banes.dev/2018/02/18/fragmented-transitions/

提交回复
热议问题