简体   繁体   English

Kotlin Recyclerview ItemClick to new Intent

[英]Kotlin Recyclerview ItemClick to new Intent

I have a problem.我有个问题。 I can print a toast message when I click on any item in Recyclerview.当我单击 Recyclerview 中的任何项目时,我可以打印一条 toast 消息。 But I want to switch to a different activity when clicked.但是我想在点击时切换到不同的活动。 Could you please help me in a very specific way?您能以非常具体的方式帮助我吗? It is a very important project for me.这对我来说是一个非常重要的项目。 The code blocks I wrote are as follows.我写的代码块如下。 Thanks in advance.提前致谢。

CustomersAdapter客户适配器

class CustomersAdapter(private val companynameArray:ArrayList,private val companyoffArray:ArrayList, private val companyPhoneArray:ArrayList): RecyclerView.Adapter<CustomersAdapter.CustomerHolder>() { class CustomersAdapter(私有 val companynameArray:ArrayList,私有 val companyoffArray:ArrayList,私有 val companynameArray:RecyclerHolderAdapter<:ArrayList)。

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

    var recycleCompanyName: TextView?=null
    var recycleOffName: TextView?=null
    var recycleOffPhone: TextView?=null


    init {
        recycleCompanyName=view.findViewById(R.id.recycleCompanyName)
        recycleOffName=view.findViewById(R.id.recycleOffName)
        recycleOffPhone=view.findViewById(R.id.recycleOffPhone)

        itemView.setOnClickListener {


        }


    }



}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomerHolder {
    val inflater= LayoutInflater.from(parent.context)
    val view= inflater.inflate(R.layout.recycler_view_customer_row,parent,false)
    return CustomersAdapter.CustomerHolder(view)
}

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

override fun onBindViewHolder(holder: CustomerHolder, position: Int) {
    holder.recycleCompanyName?.text="Şirket Adı:"+companynameArray[position]
    holder.recycleOffName?.text="Şirket Yetkilisi :"+companyoffArray[position]
    holder.recycleOffPhone?.text="İrtibat No : "+companyPhoneArray[position]
    }
}

I did not specify the activity I want to go to.我没有指定我想要 go 到的活动。 I would appreciate it if you could help as a method.如果您能作为一种方法提供帮助,我将不胜感激。

If it helps, I write the codes of the client class here.如果有帮助,我在这里编写客户端 class 的代码。

class Customers: AppCompatActivity() class 客户:AppCompatActivity()

{ {

private lateinit var auth: FirebaseAuth
private lateinit var db: FirebaseFirestore

var companynameFB:ArrayList<String> = ArrayList()
var companyoffFB:ArrayList<String> = ArrayList()
var companyphoneFB:ArrayList<String> = ArrayList()
var adapter :CustomersAdapter?=null


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

    auth= FirebaseAuth.getInstance()
    db= FirebaseFirestore.getInstance()
     getDataFromFirestore()

    var layoutManager= LinearLayoutManager(this)
    recyclerView.layoutManager=layoutManager

    adapter= CustomersAdapter(companynameFB,companyoffFB,companyphoneFB)
    recyclerView.adapter=adapter

} }

fun getDataFromFirestore(){

    db.collection("Customers")
        .addSnapshotListener { snapshot, exception ->

        if(exception!=null){

            Toast.makeText(applicationContext,exception.localizedMessage.toString(),Toast.LENGTH_LONG).show()

        }else{

            if(snapshot!=null){

                if (!snapshot.isEmpty){

                    companynameFB.clear()
                    companyoffFB.clear()
                    companyphoneFB.clear()


                    val documents=snapshot.documents
                    for (document in documents){


                        val compname=document.get("compname") as String
                        val compoff=document.get("compoff") as String
                        val compphone=document.get("compphone") as String
                        val user=document.get("user") as String
                        val timeStamp=document.get("date") as Timestamp
                        val date=timeStamp.toDate()

                        companynameFB.add(compname)
                        companyoffFB.add(compoff)
                        companyphoneFB.add(compphone)

                        adapter!!.notifyDataSetChanged()



                    }
                }
            }

        }


    }



}


override fun onCreateOptionsMenu(menu: Menu?): Boolean {

val menuInflater=getMenuInflater() menuInflater.inflate(R.menu.add_customer,menu) val menuInflater=getMenuInflater() menuInflater.inflate(R.menu.add_customer,menu)

    return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {

    if(item.itemId==R.id.add){


        val intent= Intent(this,AddCustomers::class.java)

intent.putExtra("info","new") startActivity(intent) intent.putExtra("info","new") startActivity(intent)

    }


    return super.onOptionsItemSelected(item)
}

put your click listener inside onBindViewHolder method将您的点击监听器放在onBindViewHolder方法中

override fun onBindViewHolder(holder: CustomerHolder, position: Int) {
    holder.recycleCompanyName?.text="Şirket Adı:"+companynameArray[position]
    holder.recycleOffName?.text="Şirket Yetkilisi :"+companyoffArray[position]
    holder.recycleOffPhone?.text="İrtibat No : "+companyPhoneArray[position]

 holder.itemView.setOnClickListener {
            // do what ever you want here
            holder.itemView.context.startActivity( /*your intent here*/)
        }
    }
}

Step 1: pass context here第 1 步:在此处传递上下文

class CustomersAdapter(val context:Context,private val 
companynameArray:ArrayList,private val 
companyoffArray:ArrayList, private val companyPhoneArray:ArrayList): 
RecyclerView.Adapter<CustomersAdapter.CustomerHolder>() {

step 2:第2步:

  itemView.setOnClickListener {
       val intent=Intent(context,yourActivity::java.class)
       startActivity(intent)
    }

you need a context for intent so you can get it form the activity or fragment that are associated with this adapter and pass it to your intent or you can get it from any view in your inflated layout like this您需要意图的上下文,以便您可以从与此适配器关联的活动片段中获取它并将其传递给您的意图,或者您可以从膨胀布局中的任何视图中获取它,如下所示

 val context=holder.title.context
    val intent = Intent( context, EventDetail::class.java)
    context.startActivity(intent)

For starting a new Activity you need at least a context instance.要启动一个新的活动,您至少需要一个上下文实例。 And as is written in some other answers here, you could start the activity directly inside ViewHolder with View's context.正如在此处的其他一些答案中所写的那样,您可以使用 View 的上下文直接在ViewHolder内启动活动。 But for better separations of responsibilities, I suggest you move your navigation to your Fragment/Activity , where all other navigations happen.但是为了更好地分离职责,我建议您将导航移至Fragment/Activity ,所有其他导航都在此处发生。 That way you know at the look of Activity/Fragment , which navigations could be done from that screen, and you don't need to search for some hidden navigations that happen inside Adapter or ViewHolder .这样您就知道Activity/Fragment的外观,哪些导航可以从该屏幕完成,并且您不需要搜索发生在AdapterViewHolder中的一些隐藏导航。 Also, if you need to perform startActivityForResult , then an instance of Context is not enough to do that.此外,如果您需要执行startActivityForResult ,那么Context的实例是不够的。 You need an Activity or Fragment instance for that and we have another reason to put all navigations there.为此,您需要一个ActivityFragment实例,我们还有另一个理由将所有导航放在那里。

So you can do this like that:所以你可以这样做:

ADD LAMBDA TO ADAPTER CONSTRUCTOR:将 LAMBDA 添加到适配器构造器:

class CustomersAdapter(private val companynameArray: ArrayList,
private val companyoffArray: ArrayList, 
private val companyPhoneArray: ArrayList, 
private val onItemClick: () -> Unit) : RecyclerView.Adapter<CustomersAdapter.CustomerHolder>() {

NOTE : put lambda as the last constructor parameter.注意:将 lambda 作为最后一个构造函数参数。

ADD LAMBDA TO VIEWHOLDER CONSTRUCTOR:将 LAMBDA 添加到 VIEWHOLDER CONSTRUCTOR:

class CustomerHolder(view: View, 
    private val onItemClick: () -> Unit) : RecyclerView.ViewHolder(view) {

MODIFY VIEWHOLDER CONSTRUCTOR CALL:修改 VIEWHOLDER 构造函数调用:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomerHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.recycler_view_customer_row,parent,false)
    return CustomersAdapter.CustomerHolder(view, onItemClick) //Add onItemClick lambda instance from adapter here
}

INVOKE LAMBDA ON CLICK:调用 LAMBDA 点击:

itemView.setOnClickListener {
    onItemClick()
}

FIX ADAPTER CONSTRUCTOR CALL:修复适配器构造函数调用:

val adapter = CustomersAdapter(companynameArray, companyoffArray, companyPhoneArray) {
    startActivity() // do your navigation here
}

Why did we place lambda as the last parameter of a constructor in our adapter?为什么我们将 lambda 作为适配器中构造函数的最后一个参数? If the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses( SOURCE ).如果 function 的最后一个参数是 function,则可以将作为相应参数传递的lambda表达式放在括号外。 And we did exactly that with the last junk of code above where we handle our navigation.我们正是在上面处理导航的最后一段代码中做到了这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM