【问题标题】:Kotlin Recyclerview ItemClick to new IntentKotlin Recyclerview ItemClick to new Intent
【发布时间】:2020-12-01 11:55:06
【问题描述】:

我有问题。当我单击 Recyclerview 中的任何项目时,我可以打印一条 toast 消息。但是我想在点击时切换到不同的活动。您能以非常具体的方式帮助我吗?这对我来说是一个非常重要的项目。我写的代码块如下。提前致谢。

客户适配器

类CustomersAdapter(私有val companynameArray:ArrayList,private val companyoffArray:ArrayList, private val companyPhoneArray:ArrayList): RecyclerView.Adapter() {

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]
    }
}

我没有指定我想参加的活动。如果您能提供帮助,我将不胜感激。

如果有帮助,我这里写客户端类的代码。

类客户: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)

    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") 开始活动(意图)

    }


    return super.onOptionsItemSelected(item)
}

【问题讨论】:

    标签: android kotlin android-intent android-recyclerview


    【解决方案1】:

    要启动一个新的 Activity,您至少需要一个上下文实例。正如在此处的其他一些答案中所写的那样,您可以使用 View 的上下文直接在 ViewHolder 内启动活动。但是为了更好地分离职责,我建议您将导航移动到您的Fragment/Activity,所有其他导航都发生在这里。这样您就知道Activity/Fragment 的外观,哪些导航可以从该屏幕完成,并且您不需要搜索发生在Adapter 或ViewHolder 内部的一些隐藏导航。此外,如果您需要执行startActivityForResult,那么Context 的实例是不够的。为此,您需要一个 Activity 或 Fragment 实例,我们还有另一个理由将所有导航放在那里。

    所以你可以这样做:

    将 LAMBDA 添加到适配器构造器:

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

    注意:将 lambda 作为最后一个构造函数参数。

    将 LAMBDA 添加到 VIEWHOLDER CONSTRUCTOR:

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

    修改 VIEWHOLDER CONSTRUCTOR CALL:

    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
    }
    

    点击调用 LAMBDA:

    itemView.setOnClickListener {
        onItemClick()
    }
    

    修复适配器构造函数调用:

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

    为什么我们将 lambda 作为适配器中构造函数的最后一个参数?如果函数的最后一个参数是函数,则作为相应参数传递的 lambda 表达式可以放在括号外 (SOURCE)。而我们正是在上面处理导航的最后一段代码中做到了这一点。

    【讨论】:

    • 谢谢先生 除了最后一部分,我按照我说的做了。最后一部分的代码块在哪里写? (修复适配器构造函数调用)。你能把意图部分写完整吗?
    • 我需要更多相关信息。您要打开什么活动?您想将任何其他数据传递给新活动吗?如果是,哪些数据?
    • 谢谢先生。我照你说的做了,成功了。但是我可以就不同的问题联系您吗?
    【解决方案2】:

    将您的点击监听器放入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*/)
            }
        }
    }
    

    【讨论】:

    • 谢谢先生。但是持有人不在这个领域工作
    【解决方案3】:

    第 1 步:在此处传递上下文

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

    第 2 步:

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

    【讨论】:

    • 谢谢先生。但是,当我按照您所说的进行操作时,我没有得到结果。我遇到了很多类似下面的错误。 CustomersAdapter.kt: (30, 61): Name expected CustomersAdapter.kt: (31, 46): Expecting ')' CustomersAdapter.kt: (12, 36): Unresolved reference: Context CustomersAdapter.kt: (30, 35):未解决的参考:上下文CustomersAdapter.kt:(31、39):未解决的参考:意图
    【解决方案4】:

    您需要一个 context 来表示意图,以便您可以从与此 适配器关联的 activity 或 fragment 中获取它/strong> 并将其传递给您的意图,或者您可以像这样从膨胀布局中的任何视图中获取它

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

    【讨论】:

    • 谢谢先生。我将在哪里写这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多