web-dev-qa-db-de.com

RecyclerView onitemClickListener in Kotlin

Ich schreibe meine erste App in Kotlin nach 3 Jahren Erfahrung mit Android . Ich bin nur verwirrt, wie man itemClickListener mit einem RecyclerView in Kotlin verwendet.

Ich habe versucht, das Merkmal (Edit: Now Interface) zu verwenden, sehr Java-ähnlich

public class MainActivity : ActionBarActivity() {

  protected override fun onCreate(savedInstanceState: Bundle?) {

    // set content view etc go above this line

    class itemClickListener : ItemClickListener {
      override fun onItemClick(view: View, position: Int) {
        Toast.makeText([email protected], "TEST: " + position, Toast.LENGTH_SHORT).show()
      }
    }

    val adapter = DrawerAdapter(itemClickListener())
    mRecyclerView.setAdapter(adapter)
 }

  trait ItemClickListener {
    fun onItemClick(view: View, position: Int)
  }
}

Das schien sehr überflüssig zu sein, also versuchte ich den inneren Klassenansatz:

inner class ItemClickListener {
    fun onItemClick(view: View, position: Int) {
        startActivityFromFragmentForResult<SelectExerciseActivity>(SELECT_EXERCISES)
    }
}

Und dann einfach den Klick-Listener des Adapters so einstellen:

val adapter = WorkoutsAdapter(ItemClickListener())

Aber ich bin damit nicht zufrieden, weil ich denke, dass es einen besseren und saubereren Weg gibt. Ich versuche im Wesentlichen so etwas zu erreichen: RecyclerView onClick

Irgendwelche Vorschläge?

Endete mit einer Variation der genehmigten Antwort

Definiert die Funktion in der Aktivität:

val itemOnClick: (View, Int, Int) -> Unit = { view, position, type ->
    Log.d(TAG, "test")
}

Die Funktion selbst wurde wie folgt an den Adapter übergeben:

class ExercisesAdapter(val itemClickListener: (View, Int, Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
      // other stuff up here
      val vhExercise = ExerciseVH(view) // view holder
      // on to the view holder through the extension function
      vhExercise.onClick(itemClickListener)
    }
}

Erweiterungsfunktion durch Schleife in der unten angegebenen genehmigten Antwort.

fun <T : RecyclerView.ViewHolder> T.onClick(event: (view: View, position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(it, getAdapterPosition(), getItemViewType())
    }
    return this
}
20
AfzalivE

Ich habe einen etwas anderen Ansatz. Sie können eine Erweiterung für Ihren ViewHolder erstellen

fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(getAdapterPosition(), getItemViewType())
    }
    return this
}

Dann verwenden Sie es in diesem Adapter

class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    val items: MutableList<String> = arrayListOf()

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder? {
        val inflater = LayoutInflater.from(parent!!.getContext())
        val view = inflater.inflate(R.layout.item_view, parent, false)
        return MyViewHolder(view).listen { pos, type ->
            val item = items.get(pos)
            //TODO do other stuff here
        }
    }

    override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {

    }

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


    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    }
}

Ich arbeite mit meinen Kollegen in library und biete solche Erweiterungen an.

16
Damian Petla

Meine Lösung ist wie eine Kombination der vorherigen mit einem super sauberen Aufruf aus der Aktivität. 

ContactAdapter:  

class ContactAdapter @Inject constructor() : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {

    var onItemClick: ((Contact) -> Unit)? = null
    var contacts: List<Contact> = emptyList()

    ...

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val contact = contacts[position]

        holder.email.text = contact.email
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val email: TextView = itemView.email

        init {
            itemView.setOnClickListener {
                onItemClick?.invoke(contacts[adapterPosition])
            }
        }
    }
}

ContactActivity:

override fun setupRecyclerAdapter() {
    recyclerView.adapter = contactAdapter
    recyclerView.layoutManager = LinearLayoutManager(this)

    contactAdapter.onItemClick = { contact ->

        // do something with your item
        Log.d("TAG", contact.email)
    }
}
9
denwehrle

Falls jemand nach einer no-frills - Antwort sucht, habe ich Folgendes versucht - was der Lösung von AfzalivE sehr ähnlich ist:

In meiner Adapter-Klasse habe ich die clickListener als Parameter übergeben. Bei onBindViewHolder habe ich setOnClickListener verwendet, um clickListener aufzurufen und das Click-Ereignis zu behandeln.

MyAdapter.kt :

class MyAdapter constructor(objects: ArrayList<MyObject>, val clickListener: (MyObject) -> Unit) : RecyclerView.Adapter<MyAdapter.Holder>() {

    private var mObjects : ArrayList<MyObject> = ArrayList<MyObject>()

    init {
        mObjects = objects
    }

    override fun onBindViewHolder(holder: Holder?, position: Int) {
        var item : MyObject = objects[position]

        // Calling the clickListener sent by the constructor
        holder?.containerView?.setOnClickListener { clickListener(item) }
    }

    // More code (ViewHolder definitions and stuff)...

}

Hinweis : Ich benötigte einen Verweis aus dem Container meines Listenelements (der Stammansicht), in diesem Fall containerView.

Dann habe ich mein Objekt als Parameter übergeben, ohne es erneut in einer Liste suchen zu müssen, und behandele es direkt in meiner Activity-Klasse, sobald ich den Adapter setze:

MyActivity.kt :

myRecyclerView?.adapter = MyAdapter(mObjects) {
    Log.e("Activity", "Clicked on item ${it.itemName}")
}  

Update

Wenn Sie die Position des angeklickten Elements ermitteln möchten, definieren Sie es einfach als Parameter für den Rückruf und senden Sie es später zurück. Beachten Sie die val clickListener: (MyObject, Int) -> Unit unten:

MyAdapter.kt

class MyAdapter constructor(objects: ArrayList<MyObject>, val clickListener: (MyObject, Int) -> Unit) : RecyclerView.Adapter<MyAdapter.Holder>() {
    // Rest of the code...

Bei onBindViewHolder() übergeben Sie die Position beim Aufruf der Callback-Methode:

override fun onBindViewHolder(holder: Holder?, position: Int) {
    var item : MyObject = objects[position]

    // Calling the clickListener sent by the constructor
    holder?.containerView?.setOnClickListener { clickListener(item, position) }
}

Und auf MyActivity.kt müssen Sie die Einstellung des Adapters ändern, um die Position zu erhalten. So was:

myRecyclerView?.adapter = MyAdapter(mObjects) { itemDto: MyObject, position: Int ->
        Log.e("MyActivity", "Clicked on item  ${itemDto.someItemPropertyLikeName} at position $position")
    }
5
notapotato

Ich denke, die eleganteste Lösung besteht darin, diese Verantwortung RecyclerView zu übertragen und sie nicht anzusehen oder gar anzupassen.

dazu brauchen wir:

1: RecyclerItemClickListener-Datei erstellen

class RecyclerItemClickListener(private val mRecycler: RecyclerView, private val clickListener: OnClickListener? = null, private val longClickListener: OnLongClickListener? = null) : RecyclerView.OnChildAttachStateChangeListener {

    override fun onChildViewDetachedFromWindow(view: View?) {
        view?.setOnClickListener(null)
        view?.setOnLongClickListener(null)
    }

    override fun onChildViewAttachedToWindow(view: View?) {
        view?.setOnClickListener { v -> setOnChildAttachedToWindow(v) }
    }

    private fun setOnChildAttachedToWindow(v: View?) {
        if (v != null) {
            val position = mRecycler.getChildLayoutPosition(v)
            if (position >= 0) {
                clickListener?.onItemClick(position, v)
                longClickListener?.onLongItemClick(position, v)
            }
        }
    }

    interface OnClickListener {
        fun onItemClick(position: Int, view: View)
    }

    interface OnLongClickListener {
        fun onLongItemClick(position: Int, view: View)
    }
}

2: Erweiterungen für RecyclerView erstellen/hinzufügen:

import Android.support.v7.widget.RecyclerView
import com.decathlon.manager.internal.common.RecyclerItemClickListener

fun RecyclerView.affectOnItemClick(listener: RecyclerItemClickListener.OnClickListener) {
    this.addOnChildAttachStateChangeListener(RecyclerItemClickListener(this, listener, null))
}

fun RecyclerView.affectOnLongItemClick(listener: RecyclerItemClickListener.OnLongClickListener) {
    this.addOnChildAttachStateChangeListener(RecyclerItemClickListener(this, null, listener))
}

fun RecyclerView.affectOnItemClicks(onClick: RecyclerItemClickListener.OnClickListener, onLongClick: RecyclerItemClickListener.OnLongClickListener) {
    this.addOnChildAttachStateChangeListener(RecyclerItemClickListener(this, onClick, onLongClick))
}

3: Und schließlich die Verwendung (ich nehme an, Sie verwenden Kotlinx)

import kotlinx.Android.synthetic.main.{your_layout_name}.*
class FragmentName : Fragment() {
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        recycler.affectOnItemClick(object : RecyclerItemClickListener.OnClickListener {
            override fun onItemClick(position: Int, view: View) {
                //todo
            }
        })
    }
}
3
Maxime Jallu

Sie können dies leicht erreichen, indem Sie eine Schnittstelle verwenden

class ExercisesAdapter constructor(val mItemClickListener:ItemClickListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    interface ItemClickListener{
        fun onItemClick(position: Int)
        fun onLongClick(position: Int)
    }

    inner class MyViewHolder(view:View): RecyclerView.ViewHolder(view){

        init {
            view.setOnClickListener{
                mItemClickListener.onItemClick(adapterPosition)
            }
            view.setOnLongClickListener{
                mItemClickListener.onLongClick(adapterPosition)
                [email protected] true
            }
        }
    }
}

Von Ihrer MainActivity

public class MainActivity : ActionBarActivity(), ExercisesAdapter.ItemClickListener {

   protected override fun onCreate(savedInstanceState: Bundle?) {

    // set content view etc go above this line
    mAdapter = ExercisesAdapter(this)
   }

   override fun onItemClick(position: Int) {
        Toast.makeText([email protected], "TEST: " + position, Toast.LENGTH_SHORT).show()
    }

    override fun onLongClick(position: Int) {
        //do long click here
    }
}
2
Anga Koko

Sie könnten so etwas versuchen:

public class MainActivity : ActionBarActivity() {
    protected override fun onCreate(savedInstanceState: Bundle?) {
        [...]
        val adapter = DrawAdapter(::onItemClick)
        [...]
    }
}

fun onItemClick(view: View, position: Int) {
    //Do work
}

und SAM-Konvertierung funktioniert genauso wie in Java 8, verwenden Sie also einfach ein Lambda:

public class MainActivity : ActionBarActivity() {
    protected override fun onCreate(savedInstanceState: Bundle?) {
        [...]
        val adapter = DrawAdapter({view, position -> /*Do work*/ })
        [...]
    }
}
2
D3xter

RecyclerItemClickListener  

package com.mypackage.custom 
import Android.content.Context
import Android.support.v7.widget.RecyclerView
import Android.view.GestureDetector
import Android.view.MotionEvent
import Android.view.View


@Suppress("DEPRECATION")
class RecyclerItemClickListener(context: Context, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {

    private var mGestureDetector: GestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(e: MotionEvent): Boolean {
            return true
        }
    })

    interface OnItemClickListener {
        fun onItemClick(view: View, position: Int)
    }

    override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
        val childView = view.findChildViewUnder(e.x, e.y)
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView))
            return true
        }
        return false
    }

    override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}

Für Aktivität:

 recyclerView!!.addOnItemTouchListener(
                RecyclerItemClickListener(this!!, object : RecyclerItemClickListener.OnItemClickListener {
                    override fun onItemClick(view: View, position: Int) {
                        //Write your code here
                    }
                })

Für Fragment:

recyclerView!!.addOnItemTouchListener(
                RecyclerItemClickListener(this!!.activity!!, object : RecyclerItemClickListener.OnItemClickListener {
                    override fun onItemClick(view: View, position: Int) {
                        //Write your code here
                    }
                })
1

Entschuldigung für die Verzögerung, Ich habe eine großartige Antwort von this link bekommen und es war in Java ..

Jetzt funktioniert es richtig .. Hier ist der Code,

Erstellen Sie eine Klasse mit dem Namen RecyclerItemClickListenr.

class RecyclerItemClickListenr(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {

private val mGestureDetector: GestureDetector

interface OnItemClickListener {
    fun onItemClick(view: View, position: Int)

    fun onItemLongClick(view: View?, position: Int)
}

init {

    mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(e: MotionEvent): Boolean {
            return true
        }

        override fun onLongPress(e: MotionEvent) {
            val childView = recyclerView.findChildViewUnder(e.x, e.y)

            if (childView != null && mListener != null) {
                mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView))
            }
        }
    })
}

override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
    val childView = view.findChildViewUnder(e.x, e.y)

    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
        mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
    }

    return false
}

override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}

override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}}

und greifen Sie von Aktivität/Fragment aus auf

recyclerView.addOnItemTouchListener(RecyclerItemClickListenr(this, recyclerView, object : RecyclerItemClickListenr.OnItemClickListener {

        override fun onItemClick(view: View, position: Int) {
            //do your work here..
        }
        override fun onItemLongClick(view: View?, position: Int) {
            TODO("do nothing")
        }
    }))
1
Rajesh Naddy

In RecyclerView können Sie die aufgeblasene Ansicht in der Klasse ViewHolder anklicken und von der Methode onBindViewHolder callback aufrufen. Beispiel:

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    val view = view
    val tv_message = view.tv_message
    val tv_address = view.tv_address

    fun bind(listViewItem: ListViewItem) {
        view.setOnClickListener(View.OnClickListener {

            Toast.makeText(
                view.context, 
                "Name: " + listViewItem.name + "/n Address: " + listViewItem.address, 
                Toast.LENGTH_LONG).show()
            })
        }
    }
}

Sie können die Adapter-Methode onBindViewHolder() aufrufen:

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

    val listViewItem: ListViewItem = mListViewItems[position]
    holder.tv_message.text = listViewItem.name
    holder.tv_address.text = listViewItem.address
    holder.bind(mListViewItems[position]);
}
1
rakesh rajput

Adapterkonstruktor-Deklaration  

class YourAdapter(private val mListener: (ItemObject) -> Unit) : RecyclerView.Adapter<ViewHolder>()

Adapter :: onBindViewHolder

holder.itemView.setOnClickListener {
    mListener.invoke(item) // <- item instance of ItemObject
}

Wie benutzt man

mTypesWasteAdapter = YourAdapter({ it.something()})

Grundsätzlich erhalten Sie das ItemObject als it im Lambda-Argument.

1
Lucas Montano

Zum Schluss noch eine schöne Lösung:

MyRecyclerAdapter.kt

class MyRecyclerAdapter(val context: Context, val items : ArrayList<Item>, val clickListener: (Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): RecyclerView.ViewHolder {
        return MyViewHolder(LayoutInflater.from(context).inflate(R.layout.my_item, parent, false))
    }

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

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as MyViewHolder).clickableView.setOnClickListener {
            clickListener(position)
        }
    }
}

class MyViewHolder (view: View) : RecyclerView.ViewHolder(view) {
    val clickableView = view.clickable_view
}

MainActivity.kt

fun appClickListener(position: Int) {
    // You got the position of ArrayList
}

my_recyclerview.adapter = MyRecyclerAdapter(this, myList, clickListener = {
    appClickListener(it)
})
1
Ashwin

Meine einfache Lösung, die die Funktion höherer Ordnung und die Bereichsfunktion let verwendet, um den Listener nur festzulegen, wenn itemAction festgelegt wurde

// Adapter
private var itemAction: ((Item) -> Unit)? = null

fun setItemAction(action: (Item) -> Unit) {
    this.itemAction = action
}

inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    fun setItem(item: Item) {

        // ...

        itemAction?.let {
            itemView.setOnClickListener { it(item) }
        }
    }
}

und in Aktivität/Fragment

adapter.setItemAction { // <- it is Item
  // do something with it
}
1
mustofa.id

Sie müssen keine Erweiterungsfunktion für ViewHolder oder ähnliches schreiben.
Beste Übung; Verwenden Sie Funktion höherer Ordnung  

MainRecyclerAdapter

class MainRecyclerAdapter(val news: JSONArray, private val itemClickListener: (Int) -> Unit) : RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder>() {}

Fügen Sie einfach eine Funktion höherer Ordnung hinzu. wie itemClickListener und gehen Sie dann zur ViewHolder-Klasse. Schreiben Sie diese Funktion als Parameter in Ihre Bindefunktion und setzen Sie diese auf itemView.

MainRecyclerAdapter.ViewHolder

 class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {

        fun bind(newsItem: JSONObject,itemClickListener:(Int)->Unit) {
            //Some Stuff here..

            itemView.setOnClickListener { itemClickListener(adapterPosition) }

        }
    }

Verwenden Sie diese Methode fürBindViewHolder

OnBindViewHolder

 override fun onBindViewHolder(holder: MainRecyclerAdapter.ViewHolder, position: Int) {

        holder.bind(news.getJSONObject(position),itemClickListener)
    }

Und jetzt können Sie Ihre onClick-Funktion in jede Aktivität oder Fragmente schreiben. Geben Sie einfach einen Parameter an.

Aktivität oder Fragment

val itemOnClick: (Int) -> Unit = { position ->
                newsRecyclerView.adapter!!.notifyDataSetChanged()
                Toast.makeText(this.context,"$position. item clicked.",Toast.LENGTH_SHORT).show()
            }
 newsRecyclerView.adapter = MainRecyclerAdapter(news,itemClickListener = itemOnClick)
1
faskN

OH, was zum Teufel könnte jemandem gefallen Wir stellen alle Bearbeitungs- und Mülleimer-Bilder in unser Recycling-Verzeichnis und möchten, dass etwas passiert, wenn sie angeklickt werden. Hier ist unser Kotlin-Beispiel

Dies ist eine Kartenansicht, die im Adapter aufgeblasen ist

    <RelativeLayout
    Android:id="@+id/editCLICK"
    Android:layout_width="60dp"
    Android:layout_height="60dp"
    Android:layout_marginStart="370dp"
    Android:paddingLeft="6dp"
    Android:paddingRight="6dp"
    Android:paddingTop="12dp">

    <ImageView
        Android:id="@+id/ivEdit"
        Android:layout_width="30dp"
        Android:layout_height="30dp"
        Android:background="@color/color_Transparent"
        Android:src="@drawable/ic_edit"
        Android:tint="@color/color_lightBlue" />

</RelativeLayout>

dann machen wir im Adapter einige Bindungen 

    override fun onBindViewHolder(holder: ParentViewHolder, position: Int) {
    val items = parentList[position]
    holder.item.text = items.dept


    holder.editCLICK.setOnClickListener {
        val i = Intent(context, EnterParentActivity::class.Java)
        i.putExtra("FROM", "U")
        i.putExtra("MainActId",items.idD)
        i.putExtra("PFK",items.fkD)
        i.putExtra("ET",items.dept)
        i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        context.startActivity(i)
    }
}


inner class ParentViewHolder(view: View):RecyclerView.ViewHolder(view){
    var item: TextView = view.findViewById(R.id.tvDept) as TextView
    var editCLICK: RelativeLayout = view.findViewById(R.id.editCLICK) as RelativeLayout
}

Einfach schnell und zuverlässig genießen

0
Grendel

Etwas anders, basierend auf denwehrle

Zur Verwendung in einem Fragment in OnCreateView

 adapter.onItemClick = {it ->
    //do something
 }

Fügen Sie in der Adapterklasse hinzu:

var onItemClick: ((Contact)->Unit) ?= null
...

inner class contactViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        val myItemView: TextView = itemView.findViewById(R.id.textView)

        init{
            itemView.setOnClickListener {
                onItemClick?.invoke(contact[adapterPosition])
            }
        }
}
0
LiA

// Schritt 1 mache ein Interface wie

interface RecyclerViewClickListener {
    fun onItemClick(position: String)
    fun onLongClick(position: Int)
}

Schritt 2 Übergeben Sie in der Klasse Adapter ein weiteres Argument als Schnittstelle

class ModelAdapter(var item_list: ArrayList<UploadDocument>,var mItemClickListener:RecyclerViewClickListener) : RecyclerView.Adapter<ModelAdapter.ViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModelAdapter.ViewHolder {
    // create a new view

    val view = LayoutInflater.from(parent.context).inflate(R.layout.upload_document_row_item, null)

    // create ViewHolder

    return ViewHolder(view)
}

override fun onBindViewHolder(holder: ModelAdapter.ViewHolder, position: Int) {

    holder.txtRegistrationDoc?.setText(item_list[position].getdocName())
    holder.txtCertificate?.setText(item_list[position].getcertificateName())
    holder.txtFileSize?.setText(item_list[position].getfileSize())
    holder.txtCreatedOn?.setText(item_list[position].getcreatedOn())
    holder.txtModifiedOn?.setText(item_list[position].getModifiedDate())

    //holder.chkSelected.isChecked = item_list[position].isSelected()

    holder.chkSelected.tag = item_list[position].getdocName()


        holder. chkSelected!!.setOnCheckedChangeListener { buttonView, isChecked ->

            if(isChecked)
            {
                System.out.println("position>>>"+buttonView.tag.toString())
                mItemClickListener.onItemClick(buttonView.tag.toString())
            }

        }

    //(context as UploadDocumentActivity::class.Java).onClickCalled("your argument here")

   /* holder.btn_delete.setOnClickListener(object : View.OnClickListener() {
        override fun onClick(v: View) {

            deleteItemFromList(v, position)


        }
    })*/

}

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


/*// confirmation dialog box to delete an unit
private fun deleteItemFromList(v: View, position: Int) {

    val builder = AlertDialog.Builder(v.getContext())

    //builder.setTitle("Dlete ");
    builder.setMessage("Delete Item ?")
        .setCancelable(false)
        .setPositiveButton("CONFIRM",
            DialogInterface.OnClickListener { dialog, id ->
                item_list.remove(position)
                notifyDataSetChanged()
            })
        .setNegativeButton("CANCEL", DialogInterface.OnClickListener { dialog, id -> })

    builder.show()

}*/


class ViewHolder(
    itemLayoutView: View) : RecyclerView.ViewHolder(itemLayoutView) {

    var item_name: TextView
    var txtRegistrationDoc: TextViewNormal?=null
    var txtCertificate: TextViewNormal?=null
    var txtFileSize: TextViewNormal?=null
    var txtCreatedOn: TextViewNormal?=null
    var txtModifiedOn: TextViewNormal?=null
    var chkSelected: CheckBox


    init {

        item_name = itemLayoutView.findViewById(R.id.txt_Name)
        txtRegistrationDoc = itemLayoutView.findViewById(R.id.txtRegistrationDoc)
        txtCertificate = itemLayoutView.findViewById(R.id.txtCertificate)
        txtFileSize = itemLayoutView.findViewById(R.id.txtFileSize)
        txtCreatedOn = itemLayoutView.findViewById(R.id.txtCreatedOn)
        txtModifiedOn = itemLayoutView.findViewById(R.id.txtModifiedOn)
        //btn_delete = itemLayoutView.findViewById(R.id.btn_delete_unit)
        chkSelected = itemLayoutView.findViewById(R.id.chk_selected)


    }



}
}

// Schritt 3 In deiner Aktivität/Frgament

recyclerView?.adapter = ModelAdapter(documentList,object : `in`.mobilepedia.com.gicgwaliarincubationcentre.RecyclerViewClickListener
        {
            override fun onItemClick(position: String) {

            System.out.println("Position>>>>>"+position)
        }

        override fun onLongClick(position: Int) {

        }

    })
0
sanjay sawan

Sie können OnClickListener direkt im Adapter deklarieren und eine Umleitung vornehmen, und zweitens können Sie Ihren Onclick auf Fragment/Aktivität umleiten, an der Sie den Recycleradapter festgelegt haben 

1.

 class CartAdapter(context: Context) : RecyclerView.Adapter<CartAdapter.ViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_cart, parent, false));
        }

        override fun getItemCount(): Int {
            return 10;
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
           holder.itemView.rtbProductRating.setOnClickListener{

            var iNavigation= Intent(context,MainActivity::class.Java)
            iNavigation.flags= Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
            context.startActivity(iNavigation)

// directly redirect your activity from adapter
           }

        }

        class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView)
    } 

Die zweite Möglichkeit besteht darin, Ihren Adapter umzuleiten, indem Sie auf Fragmentieren/Aktivität klicken und dann Ihre Aktivität von dort aus umleiten, anstatt vom Adapter umzuleiten

 class CartAdapter(context: Context, onClickListener: View.OnClickListener) : RecyclerView.Adapter<CartAdapter.ViewHolder>() {
        var context = context
        var onClickListener = onClickListener
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_cart, parent, false));
        }

        override fun getItemCount(): Int {
            return 10;
        }

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

//set your position to the view
            holder.itemView.rtbProductRating.tag = position

//redirect click to the fragment
            holder.itemView.rtbProductRating.setOnClickListener {
                onClickListener.onClick(holder.itemView.rtbProductRating)

            }
    //        holder.itemView.tv_waybill_count.text = holder.itemView.context.getString(R.string.waybills,5)
        }

        class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView)
    }


Your fragment will look like:

class CartFragment: BaseFragment(),View.OnClickListener {
    override val layout= R.layout.frg_cart

     override fun onClick(v: View?) {
      var position=v?.tag as Int

        if(position==0){
            var iNavigation= Intent(this,MainActivity::class.Java)
            iNavigation.flag=Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
            startActivity(iNavigation)
        }
    }

  override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        listener()
    }

    private fun listener() {
        cart_rv.adapter=CartAdapter(activity,this)
    }
}
0
Android Geek

Füge ClickListener-Code bei onBindViewHolder hinzu

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

    holder.vieww.textView.setText(arr.get(position))

    holder.vieww.setOnClickListener {(holder.vieww.textView.setTextColor(Color.GREEN))} // click event
}
0
iOS Lifee

Hier ist meine MainActivity.kt-Klasse, die Recyclerview zum Auffüllen von Standortdaten verwendet. Es verfügt über eine einfache Element-Listener-Schnittstelle, die Sie implementieren können.

    class MainActivity : AppCompatActivity() {

        private lateinit var recyclerView: RecyclerView
        private lateinit var viewAdapter: RecyclerView.Adapter<*>
        private lateinit var viewManager: RecyclerView.LayoutManager
        private var locationArrayList = arrayListOf<Location>()

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            //create locations
            var ny = Location("New York")
            var la = Location("Los Angeles")
            locationArrayList.addAll(listOf(ny, la))

            viewManager = LinearLayoutManager(this)
            viewAdapter = LocationsAdapter(locationArrayList)

            recyclerView = findViewById<RecyclerView>(R.id.recyclerView).apply {
                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                setHasFixedSize(true)

                // use a linear layout manager
                layoutManager = viewManager

                // specify an viewAdapter 
                adapter = viewAdapter

            }

    //recycler view click listener implement
            recyclerView.addOnItemClickListener(object: OnItemClickListener {
                override fun onItemClicked(position: Int, view: View) {
                    // Your logic
                    Toast.makeText([email protected], locationArrayList[position].locationName, Toast.LENGTH_SHORT).show()
                }
            })

        }

    //on item click interface
        interface OnItemClickListener {
            fun onItemClicked(position: Int, view: View)
        }

        fun RecyclerView.addOnItemClickListener(onClickListener: OnItemClickListener) {
            this.addOnChildAttachStateChangeListener(object: RecyclerView.OnChildAttachStateChangeListener {
                override fun onChildViewDetachedFromWindow(view: View?) {
                    view?.setOnClickListener(null)
                }

                override fun onChildViewAttachedToWindow(view: View?) {
                    view?.setOnClickListener({
                        val holder = getChildViewHolder(view)
                        onClickListener.onItemClicked(holder.adapterPosition, view)
                    })
                }
            })
        }
//end of interface
    }
0
Ronny Kibet

Ich habe mir diese Lösung ausgedacht, um eine Aktivität zu öffnen, wenn auf eine Zeile geklickt wird, und zwar mithilfe eines Begleitobjekts und einer zugehörigen Benutzeroberfläche. Die Aktivität wird über die Hauptaktivität geöffnet, da ich vor dem Verlassen den Listenstatus speichern musste.

Adapter

class MyAdapter(
    val dataList: List<objects.ListObject>, val listener: ItemClickListener
) : RecyclerView.Adapter<MyAdapter.ListViewHolder>()
{

    companion object {
        var mClickListener: ItemClickListener? = null
    }

    interface ItemClickListener
    {
        fun clickRow(position: Int)
    }

    override fun onBindViewHolder(holder: MyAdapter.ListViewHolder, position: Int)
    {
        holder.bindData(
            ...
        )

        mClickListener = listener
        holder.itemView.setOnClickListener { view ->

            mClickListener?.clickRow(position)
        }
    }

    ... 
}

Haupttätigkeit

val context = this
private lateinit var mMyAdapter: MyAdapter

fun initList()
{
    mMyAdapter =
        MyAdapter(dataList, object : MyAdapter.ItemClickListener
        {
            override fun clickRow(position: Int)
            {
                openActivityListItems(position)
            }
        }
    )
}

fun openActivityListItems(position : Int)
{
    recyclerViewState = mListView.getLayoutManager()?.onSaveInstanceState()

    val intent = Intent(context, ListItems::class.Java)
    intent.putExtra("Parameter1", dataList[position].Parameter1)
    intent.putExtra("Parameter2", dataList[position].Parameter2)
    context.startActivity(intent)
}
0
MadDogTannen

Wenn sich jemand für die alte Art der Umsetzung interessiert .. 

Ich habe ein vollständiges Beispiel veröffentlicht, das auch Ihren Adaptercode reduziert. Es verwendet das alte Muster des Callbacks.

Grad der Projektebene

buildscript {
    ext.kotlin_version = '1.3.10'
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.Android.tools.build:gradle:3.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-Android-extensions:$kotlin_version"//newly added

        classpath 'com.google.gms:google-services:4.1.0' // google-services plugin

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Applevel Gradle

apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-Android-extensions'
apply plugin: 'org.jetbrains.kotlin.Android.extensions'//it is used for @Percelize

Android {
    compileSdkVersion 28
    dataBinding {
        enabled = true
    }
    androidExtensions {
        experimental = true
    }
    defaultConfig {
        applicationId 'broadpeak.firebase.learning'
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

/*kapt {
    generateStubs = true
}*/
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.Android.support:appcompat-v7:28.0.0'
    implementation 'com.Android.support:design:28.0.0'
    implementation 'com.Android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.firebase:firebase-core:16.0.5'
    implementation 'com.google.firebase:firebase-firestore:17.1.3'
    implementation 'com.google.firebase:firebase-auth:16.0.5'
    implementation 'com.google.firebase:firebase-messaging:17.3.4'
    implementation 'com.google.code.gson:gson:2.8.5'

    implementation 'com.firebaseui:firebase-ui-auth:4.1.0'

    implementation 'com.github.bumptech.glide:glide:4.8.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
    ////kapt "com.Android.databinding:compiler:$Android_plugin_version"\ // not required above 3.2.0
    ///kapt "com.Android.databinding:compiler:3.1.4"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.Android.support.test:runner:1.0.2'
    androidTestImplementation 'com.Android.support.test.espresso:espresso-core:3.0.2'
}

// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'

SubjectListActivity.class

class SubjectListActivity : BaseActivity() {

    var subjects = mutableListOf<SubjectBO>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.question_list_activity)

        recycler_view.itemAnimator = DefaultItemAnimator()
        recycler_view.setHasFixedSize(true)
        recycler_view.layoutManager = LinearLayoutManager([email protected])

        db.collection("tagCollection").get().addOnSuccessListener { querySnapshot ->
            if (querySnapshot.isEmpty()) {
                Log.d(TAG, "onSuccess: LIST EMPTY")
            } else {
                // Convert the whole Query Snapshot to a list
                // of objects directly! No need to fetch each document.
                subjects = querySnapshot.toObjects(SubjectBO::class.Java)

                if(subjects.size > 0){
                    recycler_view.adapter = SubjectAdapter(subjects, object : OnRecyclerItemClickListener {
                        override fun onItemClicked(view: View?, position: Int) {
                            var intent = Intent([email protected],McqActivity::class.Java)
                            intent.putExtra("keyTagBO",subjects.get(position))
                            startActivity(intent)
                        }
                    });
                }

            }
        }.addOnFailureListener { exception ->
            exception.printStackTrace()
        }
    }

SubjectAdapter.class

class SubjectAdapter(items: List<SubjectBO>, onRecyclerItemClickListener: OnRecyclerItemClickListener)
    : BaseAdapter<SubjectBO, SubjectViewHolder>(items, onRecyclerItemClickListener) {

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): SubjectViewHolder {
        return SubjectViewHolder(parent, R.layout.item_subject, onRecyclerItemClickListener)
    }
}

SubjectViewHolder.class

class SubjectViewHolder(parent: ViewGroup, itemLayoutId: Int, onRecyclerItemClickListener:
    OnRecyclerItemClickListener) : BaseViewHolder<SubjectBO>(parent, itemLayoutId, onRecyclerItemClickListener) {

    override fun bindData(data: SubjectBO) {
        itemView.tvTitle.setText(data.tagName)
    }
}

BaseAdapter.class

abstract class BaseAdapter<T, U : BaseViewHolder<T>>
(var items: List<T>, var onRecyclerItemClickListener: OnRecyclerItemClickListener)
    : RecyclerView.Adapter<U>() {

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

    override fun onBindViewHolder(holder: U, pos: Int) {
        holder.bindData(items.get(pos))
    }
}

BaseViewHolder.class

abstract class BaseViewHolder<T : BaseModel>(parent: ViewGroup, @LayoutRes itemLayoutId: Int,
                                             var onRecyclerItemClickListener: OnRecyclerItemClickListener) :
        RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(itemLayoutId, parent,
                false)), View.OnClickListener {

    override fun onClick(v: View?) {
        onRecyclerItemClickListener.onItemClicked(v, adapterPosition)
    }

    abstract fun bindData(data: T)

    init {
        itemView.setOnClickListener(this)
    }
}

OnRecyclerItemClickListener.class

interface OnRecyclerItemClickListener{
    fun onItemClicked(view: View?, position: Int)
}
0
Xar E Ahmer