我尝试使用共享元素实现两个片段之间的转换。
FragmentA
有一个托管条目的 RecycleViewer。每个条目都有一个按钮,单击后会将条目转换为可编辑条目的 FragmentB
。此转换按预期工作,但是当调用 popBackStack()
将元素转换回 FragmentA
中的 RecycleViewer 时,我无法实现转换。
这是我的
FragmentA
,它托管 RecyleViewer:
class FragmentA : Fragment() {
private var _binding: FragmentABinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCreateBinding.inflate(inflater, container, false)
...
return binding.root
}
}
这是参赛作品的
AdapterClass
:
class Adapter(
private val context: Context,
private var entries: MutableList<Entry>
) : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.entry, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
...
holder.itemView.transitionName = "entry_$position"
holder.button.setOnClickListener {
val fragmentManager = (context as AppCompatActivity).supportFragmentManager
val editFragment = FragmentB()
val bundle = Bundle()
bundle.putInt("entryPosition", position)
editFragment.arguments = bundle
fragmentManager.beginTransaction()
.addSharedElement(holder.itemView, holder.itemView.transitionName)
.addToBackStack(null)
.replace(R.id.fragmentContainerView, editFragment)
.commit()
}
}
}
这是
FragmentB
,用于编辑条目:
class FragmentB : Fragment() {
private var _binding: FragmentBBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentEditFlagBinding.inflate(inflater, container, false)
binding.entry.root.transitionName = "entry_${arguments?.getInt("entryPosition")}"
...
binding.saveButton.setOnClickListener {
requireActivity().supportFragmentManager.popBackStack()
}
return binding.root
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedElementEnterTransition = MaterialContainerTransform().apply {
duration = 500
scrimColor = Color.TRANSPARENT
}
sharedElementReturnTransition = MaterialContainerTransform().apply {
duration = 500
scrimColor = Color.TRANSPARENT
}
}
}
我已阅读文档,尤其是这部分是我认为我需要的。我尝试推迟动画,因为我认为我需要等到进入 FRagmentA 时的所有视图都已测量并放置,尤其是 Recycleviewer。
class FragmentA : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
viewModel.data.observe(viewLifecycleOwner) {
adapter.setData(it)
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
}
}
}
我还尝试为 FragmentA 设置
sharedElementEnterTransition
并为每个条目提供了唯一的 ID,但这似乎也没有帮助,我认为我使用的位置应该足够了,因为我不会从我的 FragmentB
更改我的条目列表.
已解决,稍后发布解决方案