使用 RecycleViewer 中的共享元素进行 Android 转换

问题描述 投票:0回答:1

我尝试使用共享元素实现两个片段之间的转换。

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
更改我的条目列表.

android kotlin android-fragments android-recyclerview android-transitions
1个回答
0
投票

已解决,稍后发布解决方案

© www.soinside.com 2019 - 2024. All rights reserved.