【问题标题】:Recyclerview onclick to open new fragmentRecyclerview onclick 打开新片段
【发布时间】:2025-12-29 05:30:16
【问题描述】:

我在片段中有recycleview。当我单击 recyclerview 中的一项时,我想打开新片段。如您所见,我必须在我的适配器中列: 我还创建了两个片段。(fragment_opel 和片段雪佛兰。)当用户单击雪佛兰行时,片段雪佛兰必须打开。我是 android studio 的新手。我创建 onclick我的适配器中的方法。但我不能填补那个功能。 :) 你能帮我解决一下吗?

我的适配器:

package com.example.parcaburada



class AracMarkaAdapter(tumKategori: ArrayList<AracMarka>) :
    RecyclerView.Adapter<AracMarkaAdapter.AracMarkaViewHolder>() {


    var araclar = tumKategori

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AracMarkaViewHolder {

        var inflater = LayoutInflater.from(parent.context)
        var arackategori = inflater.inflate(R.layout.arac_kategori, parent, false)

        return AracMarkaViewHolder(arackategori)

    }

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

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


        holder.aracismi.text = araclar.get(position).aracAdi
        holder.aracLogo.setImageResource(araclar.get(position).aracLogo)


    }


    class AracMarkaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
        View.OnClickListener {
        override fun onClick(v: View?) {


        }


        var teksatirKategori = itemView
        var aracismi = teksatirKategori.tvaracAdi
        var aracLogo = teksatirKategori.img_arac_sembol
    }


}

我的片段:

package com.example.parcaburada.ui.kategori



class KategoriFragment : Fragment() {
    var araclarKategori = ArrayList<AracMarka>()


    private lateinit var galleryViewModel: GalleryViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        veriKaynaginiDoldur()
        galleryViewModel =
            ViewModelProviders.of(this).get(GalleryViewModel::class.java)
        var root = inflater.inflate(R.layout.fragment_category, container, false)

        var rvarackategori = root.findViewById(R.id.rvarackategori) as RecyclerView
        var MyAdapter = AracMarkaAdapter(araclarKategori)
        rvarackategori.adapter = MyAdapter

        var linearLayoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        rvarackategori.layoutManager = linearLayoutManager

        return root
    }

    fun veriKaynaginiDoldur(): ArrayList<AracMarka> {

        var aracLogo = arrayOf(R.drawable.opellogo, R.drawable.chevroletlogo)
        var aracismi = resources.getStringArray(R.array.arabaisim)

        for (i in 0 until min(aracismi.size, aracLogo.size)) {

            var eklenecekaracKategori = AracMarka(aracismi[i], aracLogo[i])
            araclarKategori.add(eklenecekaracKategori)
        }
        return araclarKategori

    }

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

    }


}

【问题讨论】:

  • 我在您的代码中的任何地方都没有看到点击监听器。 Have you gone through this post?。就是设置一个监听器,然后你就可以为所欲为。
  • 你想在适配器还是在活动中做?
  • @Danialclarc recyclerview 定义了我的片段。所以我必须在适配器上定义。
  • @TaseerAhmad 我在我的适配器上定义了点击监听器。你可以看到。但它是空的。因为我现在不知道该怎么做。也许我完全错了。

标签: android kotlin android-recyclerview


【解决方案1】:

以防万一这有助于任何使用 Kotlin 和 Android Studio 4 的人。

我在片段中的 RecycleView 上使用适配器。如果要显示新的片段视图,您只能在 mainactivity.kt 类而不是适配器类中进行覆盖,因为它不在主线程上。

所以我的 recyclerview 适配器中的构造函数更改为:

class MyFollowRecyclerViewAdapter(
    private val values: List<FollowItem>,
    private val context: Context
)

然后我的适配器类中有一个变量:

 private val clickHandler: ClickEventHandler = context as ClickEventHandler

然后我将适配器类中的 setOnClickListener 添加到 onCreateViewHolder 方法中:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(layout.fragment_item_follow, parent, false)
        view.setOnClickListener {
            clickHandler.viewFollow(it)
        }
        return ViewHolder(view)
    }

ClickEventHandler 在我的适配器类中定义为:

  interface ClickEventHandler {
        fun viewFollow(holder: View)
    }

现在是 mainactivity 中函数的覆盖。我将 ClickEventListener 添加到我的 MainActivity 类中:

class MainActivity : AppCompatActivity(), ClickEventHandler {

然后我在我的 mainactivity 类中创建我的适配器类中定义的函数的覆盖函数:

 override fun viewFollow(holder: View) {
}

【讨论】:

    【解决方案2】:

    首先设置一个点击监听:

    ViewHolder 对象上设置点击监听器。

      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AracMarkaViewHolder {
    
        var inflater = LayoutInflater.from(parent.context)
        var arackategori = inflater.inflate(R.layout.arac_kategori, parent, false)
    
        return AracMarkaViewHolder(arackategori).also {
           arackategori.setOnClickListener { clickHandler.forwardClick(it) }
        }
    }
    

    我们设置了一个监听器,我们在其中调用函数forwardClick(holder: AracMarkaViewHolder)。我们将当前膨胀的视图持有者引用传递给它,以便我们可以对它进行任何未来的操作。

    现在设置一个接口:

    我们创建一个界面是因为我们希望任何点击事件都由 Activity 处理。在您的情况下,这些事件包括启动一个新片段。

    interface ClickEventHandler {
        fun forwardClick(holder: AracMarkaViewHolder)
    }
    

    现在在您的适配器中,设置如下界面:

    private val clickHandler: ClickEventHandler = context as ClickEventHandler 
    

    修改适配器类签名:

    现在,我们需要稍微修改适配器的构造函数。

    var MyAdapter = AracMarkaAdapter(araclarKategori, requireContext()) //We pass the activity's context. 
    

    您的适配器类签名应该如下所示:

     class AracMarkaAdapter(tumKategori: ArrayList<AracMarka>, context: Context) :
       RecyclerView.Adapter<AracMarkaAdapter.AracMarkaViewHolder>() {
            private val clickHandler: ClickEventHandler = context as ClickEventHandler 
      }   
    

    实现接口:

    现在我们在 Activity 中实现接口。

    class MainActivity : AppCompatActivity(), ClickEventHandler  {
      override fun forwardClick(holder: AracMarkaViewHolder) {
         //Launch a new fragment here.
      }
    }
    

    【讨论】:

    • 你好泰瑟。太感谢了。我根据您的建议安排我的代码。但是,对于此代码:val clickHandler: ClickEventHandler = context as ClickEventHandler, context cannot resolve.
    • 您需要将context 传递给适配器类。例如class Adapter(context: Context)。然后,Adapter(this).
    • 抱歉我的问题,但我无法得到它。
    • 检查编辑,您只需将context 作为参数传递给适配器类,就像您将列表传递给它一样。
    • 您好 Taseer,非常感谢您的帮助。问题出在 AracMarkaAdapter 类中,AracMarkaViewHolder 是 uresolve。
    【解决方案3】:

    只需像这样在您的onBindViewHolder 方法中实现“转到片段”-

    override fun onBindViewHolder(holder: AracMarkaViewHolder, position: Int) {
        holder.aracismi.text = araclar.get(position).aracAdi
        holder.aracLogo.setImageResource(araclar.get(position).aracLogo)
        holder.setOnClickListener {
            if (position == 0) {
                TODO("Go to first fragment")
            } else {
                TODO("Go to second fragment")
            }
        }
    }
    

    【讨论】:

    • 您好,非常感谢。现在我可以得到职位。但是现在,要转到第一个片段,我不能调用“supportFragmentManager”。你现在如何做到这一点?
    • onBindVIewHolder 中设置监听器是一种不好的做法,因为在滚动时,它会继续在每个视图持有者上设置点击监听器。此外,处理该逻辑不是适配器类的工作。它应该传播到活动级别并在那里处理。
    【解决方案4】:

    您需要为您的适配器实现一个 onClickListener 接口。 之后,您可以设置您的 recyclerview 可见性消失和 frameLayout Visible。 现在将您想要的片段发送到 frameLayout。

    在您的主要活动中实现适配器 onClickListener 并通过选定的 recyclerview 项目索引显示您想要的片段

    【讨论】:

    • 感谢您的帮助。第二个建议,我的 recyclerview 在我的片段中。所以我的主要活动是空的。我应该在我的 mainactiviy 上实现适配器 onClickListener 吗?还是在片段中使用?
    • 包含一些代码将有助于读者正确理解解决方案。
    • @akiilhan 您想更改已经传递到 frameLayout 并且已经在 mainActivity 中定义的片段,对吗?在这种情况下,您应该在 mainActivity 中实现适配器 onClickListener 并用 FragmentTransaction 替换第二个片段。
    • @TaseerAhmad 抱歉。这就是我现在可以提供帮助的方式。你的回答做得最多。
    • @HoseinHaqiqian 我使用 recyclerview 创建了两行。但是我在我的片段中创建了 recyclerview,而不是在我的主要活动中。我的目的是当我单击行时,应该打开不同的片段。实际上我现在如何使用按钮将数据片段传递给片段。但现在没有按钮,我正在使用 recyclerview。我很困惑。