【问题标题】:Add Listener into ViewHolder for fragement to communication with Activity在 ViewHolder 中添加 Listener 用于 Fragment 与 Activity 通信
【发布时间】:2021-07-09 06:29:22
【问题描述】:

当从片段 A 中的 Recycler 视图中检测到对项目的点击时,我试图触发片段 B 的开始。

我的做法是:

  • MainActivity 启动 Fragment A 并显示 CardView 列表
  • 一旦用户点击其中一个 CardView,接口调用主 Activity 中实现的点击方法来启动 Fragment B

MainActivity.kt

class MainActivity : AppCompatActivity(), OnLocationSelectedListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if(savedInstanceState == null) { // initial transaction should be wrapped like this
            --Start Fragment A
        }
    }

    override fun onLocationSelected(id: String) {
        replaceFragment(FragmentB(), R.id.listcontainer, id)
    }

    companion object {
        val LOCATION_ID: String = "location_id"
    }
}

接口定义在:OnLocationSelectedListener.kt

interface OnLocationSelectedListener {
    fun onLocationSelected(id: String)
}

必须从链接到 Fragment B 的适配器调用监听器

class FragmentBAdapter(

    var listOfLocations: List<RestaurantLocation>) : RecyclerView.Adapter<LocationsListAdapter.ViewHolder>() {

    private lateinit var onLocationSelectedListener: OnLocationSelectedListener


    override fun getItemCount(): Int {
        return listOfLocations.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocationsListAdapter.ViewHolder {
        return ViewHolder(
            parent.context,
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.location_item,
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bindViewHolder(listOfLocations[position])
    }

    inner class ViewHolder(private val context: Context, private val viewDataBinding: LocationItemBinding) :
        RecyclerView.ViewHolder(viewDataBinding.root) {

        fun bindViewHolder(location: RestaurantLocation) {
            viewDataBinding.locationName.text = location.name
            viewDataBinding.cardItem.setOnClickListener {
                onLocationSelectedListener.onLocationSelected(location.id)
            }

        }
    }

}

我有一个异常弹出,因为lateinit property onLocationSelectedListener has not been initialized

不明白怎么初始化?

有什么想法吗? 谢谢

【问题讨论】:

    标签: android kotlin interface


    【解决方案1】:

    您需要将侦听器传递给 FragmentBAdapter 的构造函数,如下所示:

    class FragmentBAdapter(val onLocationSelectedListener: OnLocationSelectedListener)
    

    您的 Activity 是一个 OnLocationSelectedListener,因此在您创建适配器的 Fragment 中,可能在 onCreateView() 中,您可以这样做

    adapter = FragmentBAdapter(activity as? OnLocationSelectedListener)
    

    【讨论】:

      【解决方案2】:

      由于您的 MainActivity 中有 onLocationSelectedListener 的实现,您可以将 MainActivity 的对象传递给 FragmentBAdapter 并通过 MainActivity 对象在 FragmentBAdapter 的构造函数中初始化 onLocationSelectedListener

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-18
        • 2017-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多