问题描述
我阅读了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 之类的引用时始终要注意内存泄漏)但它可以完成工作