安卓返回转换在 5 秒后不起作用



使用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_width="match_parent"
android:layout_height="wrap_content"
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(上测试了这一点。所有人都表现出相同的行为。

我想明白了。问题出现在主片段的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直到动画运行后才设置adpader。

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

最新更新