You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过DataBinding获取RecyclerView子项中MotionLayout的引用?

解决RecyclerView子项中MotionLayout的TransitionListener绑定问题

核心逻辑

MotionLayout属于RecyclerView的子项布局,无法直接通过Fragment的DataBinding获取引用,必须在RecyclerView的Adapter中处理子项的MotionLayout实例,这才是正确的绑定路径。

具体实现步骤

  1. 给子项的MotionLayout设置唯一ID
    在row_shipper_line.xml中,确保MotionLayout有明确的id:

    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/line_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!-- 子项内部布局内容 -->
    </androidx.constraintlayout.motion.widget.MotionLayout>
    
  2. 在Adapter中通过子项DataBinding获取引用
    利用子项布局的DataBinding类,直接获取MotionLayout实例并绑定监听器:

    class ShipperAdapter(private val transitionListener: MotionLayout.TransitionListener) :
        RecyclerView.Adapter<ShipperAdapter.ViewHolder>() {
    
        inner class ViewHolder(private val binding: RowShipperLineBinding) :
            RecyclerView.ViewHolder(binding.root) {
    
            fun bind() {
                // 给子项的MotionLayout绑定监听器
                binding.line_container.addTransitionListener(transitionListener)
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val inflater = LayoutInflater.from(parent.context)
            val binding = RowShipperLineBinding.inflate(inflater, parent, false)
            return ViewHolder(binding)
        }
    
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.bind()
        }
    
        override fun getItemCount(): Int {
            // 返回你的数据集长度
        }
    }
    
  3. 在Fragment中传递监听器给Adapter
    将你准备好的TransitionListener作为参数传入Adapter,完成绑定:

    class YourFragment : Fragment() {
        private lateinit var binding: YourFragmentBinding
        private val myTransitionListener = object : MotionLayout.TransitionListener {
            override fun onTransitionStarted(motionLayout: MotionLayout?, startId: Int, endId: Int) {
                // 触发过渡开始时的逻辑
            }
    
            override fun onTransitionChange(motionLayout: MotionLayout?, startId: Int, endId: Int, progress: Float) {
                // 过渡进度变化时的逻辑
            }
    
            override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
                // 过渡完成时的逻辑
            }
    
            override fun onTransitionTrigger(motionLayout: MotionLayout?, triggerId: Int, positive: Boolean, progress: Float) {
                // 触发过渡触发器时的逻辑
            }
        }
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = YourFragmentBinding.inflate(inflater, container, false)
            // 初始化RecyclerView并设置Adapter
            binding.shipper_list.adapter = ShipperAdapter(myTransitionListener)
            return binding.root
        }
    }
    
  4. 关键注意点

    • 不要在Fragment中直接遍历RecyclerView查找子项,RecyclerView的子项是复用机制,这种方式会导致引用混乱或空指针。
    • 如果需要在Fragment中响应子项MotionLayout的事件,可以在Adapter中定义回调接口,将事件从子项传递回Fragment。

内容的提问来源于stack exchange,提问作者Mark Löwe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:20:28