在适配器中单击项目时添加片段

问题描述

我阅读了this,但找不到答案。

我只想在点击 Fragment 中的任何项目时添加 listView。我尝试访问 getSupportFragmentManager 以实现 Fragment,但无法访问它。我实例化了 FragmentActivity 类,然后调用supportFragmentManager。现在面临上述以下错误

java.lang.IllegalStateException:FragmentManager 尚未附加到主机。

请告诉我哪里做错了。

class AnimalAdapter : BaseAdapter {
        var context: Context
        var listofAnimals: List<Animal>? = null

        constructor(listofAnimals: List<Animal>?,context: Context) : super() {
            this.listofAnimals = listofAnimals
            this.context = context
        }

        override fun getCount(): Int {
            return listofAnimals!!.size
        }

        override fun getItem(position: Int): Any {
            return listofAnimals?.get(position)!!
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        @SuppressLint("ViewHolder")
        override fun getView(position: Int,convertView: View?,parent: ViewGroup?): View {
            val animal = listofAnimals?.get(position)

            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            val rowView: View
            if (animal?.isKiller!!) {
                rowView = inflater.inflate(R.layout.layout_killer_animal_ticket,parent,false)
            }
            else{
                rowView = inflater.inflate(R.layout.animal_ticket,false)
            }
            val imageAnimal = rowView.findViewById<ImageView>(R.id.image_animal)
            val textNameAnimal = rowView.findViewById<TextView>(R.id.text_animal_name)
            val textAnimalDesc = rowView.findViewById<TextView>(R.id.text_animal_description)

            imageAnimal.setimageResource(animal?.image!!)
            textNameAnimal.text = animal.name
            textAnimalDesc.text = animal.des

            rowView.setonClickListener{

                val fragmentActivity = FragmentActivity()

                fragmentActivity.supportFragmentManager.commit {
                    val fragmet: Fragment = AnimalDescriptionFragment()
                    replace(R.id.animal_desc_fragment_contianer,fragmet)
                    addToBackStack("animal_desc_frag")
                }

            }



            return rowView
        }


    }

解决方法

您根本无法创建本地 Activity (val fragmentActivity = FragmentActivity()),它只是一些内存分配,但此 Activity 已死。您必须保留对已存在并显示的 Activity 的引用,其中包含您的适配器

在你的构造函数中使用 var context: Context 而不是 var fragmentActivity: FragmentActivity ,然后你可以使用 fragmentActivity.supportFragmentManager.commit... - 只需保持对活着的 Activity 的引用,而不是新创建的对象

,

老实说,你应该把这些东西分开——一个适配器是用来把数据集变成某种视觉显示的,它不应该直接控制应用程序 UI 的其他部分,弄乱后台堆栈等。

理想情况下,您应该拥有某种可以在单击项目时更新的侦听器。就是这样,适配器只是“嘿,这被点击了”,也许提供了一些关于它的细节,由听众(如果有的话)决定如何处理。

可能最好使用的是 ViewModel - 将它传递给适配器,有一个可以设置的 currentItem LiveData 值,然后其他组件可以 {{1} }} 该值并对其做出反应。适配器不需要知道他们在做什么。

快速而肮脏的方法是只在父 observe 上有一个方法,例如 Activity,将其传递给 onAnimalItemClicked(),并在需要时调用该方法。除非您为 Activity 实现的方法创建接口,否则您将需要使用特定的 Activity 类。这并不理想(并且在保持对 Activity 之类的引用时始终要注意内存泄漏)但它可以完成工作