5秒后Android返回过渡不起作用

Posted

技术标签:

【中文标题】5秒后Android返回过渡不起作用【英文标题】:Android return transition doesn't work after 5 seconds 【发布时间】:2021-07-08 13:44:10 【问题描述】:

使用 androidX 导航组件,我在两个片段之间创建了共享元素转换。第一个片段有一个 RecyclerView,第二个片段显示点击元素的详细信息。 enter 转换总是按预期工作。如果我立即按下后退按钮,则返回过渡有效。但是,如果我在点击后退按钮之前等待超过 5 秒,动画将无法正常工作。

在这种情况下,根本就没有动画。没有移动,没有淡出,片段中的所有内容都立即显示在原地。

这是主片段中的导航代码:

    override fun onClick(deck: SlideDeck, sourceView: View) 
        viewModel.activeDeck = deck
        val extras = FragmentNavigatorExtras(sourceView to "deck_details")
        findNavController().navigate(
            R.id.action_deckListFragment2_to_deckDetailsFragment,
            null,
            null,
            extras
        )
    

这是在第二个片段中设置共享元素转换的代码:

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        val animation = TransitionInflater.from(requireContext()).inflateTransition(
            android.R.transition.move
        )
        sharedElementEnterTransition = animation
        sharedElementReturnTransition = animation
        binding = FragmentDeckDetailsBinding.inflate(inflater, container, false)
        return binding.root
    

最后,回到主片段,我不得不推迟进入过渡:

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        // Inflate the layout for this fragment
        binding = FragmentDeckListBinding.inflate(inflater, container, false)
        postponeEnterTransition()
        binding.root.doOnPreDraw 
            startPostponedEnterTransition()
        
        return binding.root
    

我还必须确保 RecyclerView 中的每个元素都有一个唯一且一致的 transitionName,如下所示:

    <androidx.cardview.widget.CardView
        android:id="@+id/deckDetailsCard"
        android:layout_
        android:layout_
        android:layout_marginTop="4dp"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        app:cardCornerRadius="4dp"
        android:transitionName="@String.format(@string/transition_name_string, deck.id)"
        android:onClick="@() -> itemClickListener.onClick(deck, deckDetailsCard)">
        ...
    </androidx.cardview.widget.CardView>

再一次,这一切都按预期进行,除非我在返回主片段之前等待超过约 5 秒。我已经在 2 个仿真器(SDK 21 和 28)和一个物理设备(Galaxy S10E)上对此进行了测试。都表现出相同的行为。

【问题讨论】:

【参考方案1】:

我想通了。问题出在主要片段的onViewCreated

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        val deckObserver = Observer<List<SlideDeck>>  deckList ->
            val listener: DeckListOnItemClickListener = this
            val deckListAdapter = DeckListAdapter(requireContext(), deckList,
                listener)
            deckListAdapter.dataSet = deckList
            binding.deckRecyclerView.adapter = deckListAdapter
            deckListAdapter.notifyDataSetChanged()
        
        viewModel.deckList.observe(viewLifecycleOwner, deckObserver)
    

你看到了吗?

在收到来自 ViewModel 的更改通知之前,我没有为 RecyclerView 创建适配器。我认为问题在于 RecyclerView 直到动画运行后才设置 adpater。

所以我将适配器设置为 Fragment 的成员,将 RecyclerView 的 adapter 成员直接设置在 onViewCreated 中,然后在观察到更改时更新适配器的列表。这似乎已经解决了。

【讨论】:

以上是关于5秒后Android返回过渡不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 连接检测在 60 秒后不起作用

FragmentNavigator 共享过渡不起作用

不透明度过渡在两个方向上都不起作用

为啥 opacity 过渡不起作用,并且 Jobs 组件突然出现没有 opacity 过渡?

过渡在悬停时不起作用

背景图像过渡在CSS中不起作用[重复]