如何使用接口android在适配器中创建onclick事件?

Posted

技术标签:

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

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

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

【问题讨论】:

“接口”是什么意思? kotlinlang.org/docs/reference/interfaces.html ?你能分享一些代码吗? 上传你的代码 点击接口已经是监听器。所以,你又加了一个? 【参考方案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)
            
        )
    

【讨论】:

以上是关于如何使用接口android在适配器中创建onclick事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android Studio中创建入门芯片填充?

android的adapter能不能在onResume方法中创建

如何膨胀由 Android Studio 向导在 Activity 中创建的片段(列表)?

如何在 Retrofit 中创建用于暂停功能的调用适配器?

如何在 .NET 中创建虚拟网络适配器?

在使用第三方API并在Laravel中创建域时使用适配器模式