【问题标题】:How to create onclick event in adapter using interface android?如何使用接口android在适配器中创建onclick事件?
【发布时间】:2018-02-14 23:59:23
【问题描述】:

如何使用界面创建点击事件?

在我的应用程序中,我创建了视图单击界面来检测将适配器项单击到父活动中。在适配器中创建接口和方法后,如何使用此接口调用视图侦听器?

【问题讨论】:

标签: android kotlin adapter baseadapter


【解决方案1】:

请检查此代码,它对我来说工作正常。

首先创建适配器类。

class ChapterAdapter(private val activity: Activity, val mWords: ArrayList<Chapter>, val btnlistener: BtnClickListener) : RecyclerView.Adapter<ChapterAdapter.ViewHolder>() {

        companion object {
            var mClickListener: BtnClickListener? = null
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            return ViewHolder(layoutInflater.inflate(R.layout.layout_capter_raw, parent, false))
        }

        override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
            mClickListener = btnlistener
            val item = mWords[position]

            holder.layout_chapter_name.setOnClickListener(object : View.OnClickListener {
                override fun onClick(v: View?) {
                    if (mClickListener != null)
                        mClickListener?.onBtnClick(position)
                }
            })
        }

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

        override fun getItemId(position: Int): Long {
            return super.getItemId(position)
        }

        override fun getItemViewType(position: Int): Int {
            return super.getItemViewType(position)
        }

        class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val txt_capter_name = view.txt_capter_name
        }

        open interface BtnClickListener {
            fun onBtnClick(position: Int)
        }
    }

在您的 Activity 或 Fragment 中创建并声明适配器之后。

listAdapter = ChapterAdapter(activity, _arrChapterList, object : ChapterAdapter.BtnClickListener {
                override fun onBtnClick(position: Int, chapter_id: String, chapter_size: String, chapter_name: String) {
                    toast(chapter_id + " = " + chapter_size, Toast.LENGTH_LONG)
                }
            })

【讨论】:

  • 这不是使用 Kotlin 的方式。如果转换器尝试将 java 转换为 kotlin,它就是这样 :)
  • mClickListener?.onBtnClick(position) 应该使用而不是空检查,然后使用!!。我想知道你为什么将BtnClickListener 放在伴生对象中?
  • 如果您在 Android Studio 中使用“Convert Java -> Kotlin”转换器,这就是自动生成代码的工作原理
【解决方案2】:

在 Kotlin 中,正确的做法是使用回调而不是 Java Interfaces。示例:

class MyAdapter(private val callback: (YourModel) -> Unit) {

    override fun onBindViewHolder(holder: DataBoundViewHolder<YourModel>, position: Int) {
        bind(holder.binding, items!![position])
        holder.binding.executePendingBindings()
        holder.binding.root.setOnClickListener { callback(binding.model) }
   }
}

并使用在某处创建适配器

MyAdapter myAdapter = MyAdapter( { println{"Clicked $it"} })

编辑:由于提问者希望看到完整的工作代码,我使用了来自 Sumit 的代码并将接口替换为 Kotlin-Callbacks。

class ChapterAdapter(private val activity: Activity, 
     val mWords: ArrayList<Chapter>,
     val callback: (Any) -> Unit) : 
     RecyclerView.Adapter<ChapterAdapter.ViewHolder>() {


        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            return ViewHolder(layoutInflater.inflate(R.layout.layout_capter_raw, parent, false))
        }

        override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
            val item = mWords[position]

            holder.layout_chapter_name.setOnClickListener( callback {$it})
        }

        override fun getItemCount(): Int = mWords.size

        override fun getItemId(position: Int): Long = super.getItemId(position)

        override fun getItemViewType(position: Int): Int = super.getItemViewType(position)


        class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val txt_capter_name = view.txt_capter_name
        }

最后创建适配器

listAdapter = ChapterAdapter(activity, _arrChapterList, { 
  toast( "Clicked $it", Toast.LENGTH_LONG) 
})

【讨论】:

  • 使用 lambda 表达式这是镜头解决方案
  • Kotlin SAM-Type :-)
  • 你能提供完整的代码吗?接口怎么可能?
  • 修改了我的示例。未经测试,但这就是它的方式。注意,示例代码有一些错误......例如,您不应该使用“ID”,您应该使用 holder.root.setOnClickListener { .. }
  • 我在 $it“期望一个元素”上收到错误消息。我如何将位置传递回适配器的托管片段?
【解决方案3】:

我有同样的问题,这是我的解决方案:

package adapter

class MarketplaceListAdapter : RecyclerView.Adapter<MarketplaceListAdapter.ViewHolder> {

    private val marketplaceList: ArrayList<Marketplace>

    constructor(marketplaceList: ArrayList<Marketplace>) : super() {
        this.marketplaceList = marketplaceList
    }

    private var listener: OnItemClickListener? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // implementation
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // implementation
    }

    override fun getItemId(position: Int): Long {
        return 0
    }

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

    fun setListener(listener: OnItemClickListener) {
        this.listener = listener
    }

    interface OnItemClickListener {
        fun onItemClick(marketplace: Marketplace)
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
        View.OnClickListener {

        var tvTitle: TextView = itemView.findViewById(R.id.tvTitle)
        var ivIcon: ImageView = itemView.findViewById(R.id.ivIcon)

        init {
            itemView.setOnClickListener(this)
        }

        override fun onClick(v: View) {
            listener?.onItemClick(marketplaceList[adapterPosition])
        }

    }

}

在我的片段上:

val list = view.findViewById<RecyclerView>(R.id.list)

list?.let {
    adapter?.let { adapter ->
        list.adapter = adapter

        adapter.setListener(object : MarketplaceListAdapter.OnItemClickListener {
            override fun onItemClick(marketplace: Marketplace) {
                onMarketplaceSelected(marketplace)
            }
        })
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多