在适配器中单击项目时添加片段
Add Fragment when item is clicked in adapter
我阅读了 但找不到答案。
我只想在单击 listView
中的任何项目时添加 Fragment
。我试图访问 getSupportFragmentManager
来实现 Fragment 但无法访问它。我实例化了FragmentActivity
class然后调用了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, parent, 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 fragmentActivity: FragmentActivity
而不是 var context: Context
然后你可以使用 fragmentActivity.supportFragmentManager.commit...
- 只需保持对活动 Activity
的引用,而不是新创建的对象
老实说,你应该把这些东西分开 - 一个适配器可以将数据集转换成某种视觉显示,它不应该直接控制应用程序的其他部分 UI,弄乱后栈等
理想情况下,您应该有某种可以在单击项目时更新的侦听器。就是这样,适配器只是说“嘿,这个被点击了”,也许会提供一些关于它的细节,然后由听众(如果有的话)决定如何处理。
最好使用的可能是 ViewModel
- 将其传递给适配器,有一个可以设置的 currentItem
LiveData
值,然后其他组件可以 observe
该值并对其做出反应。适配器不需要知道他们在做什么。
快速而肮脏的方法是在父 Activity
上有一个方法,例如 onAnimalItemClicked()
,将其传递给 Adapter
,并在需要时调用该方法到。您需要使用特定的 Activity class 除非您为 Activity 实现的方法创建接口。这并不理想(并且在保持对 Activity 之类的引用时始终要注意内存泄漏)但它完成了工作
我阅读了
我只想在单击 listView
中的任何项目时添加 Fragment
。我试图访问 getSupportFragmentManager
来实现 Fragment 但无法访问它。我实例化了FragmentActivity
class然后调用了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, parent, 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 fragmentActivity: FragmentActivity
而不是 var context: Context
然后你可以使用 fragmentActivity.supportFragmentManager.commit...
- 只需保持对活动 Activity
的引用,而不是新创建的对象
老实说,你应该把这些东西分开 - 一个适配器可以将数据集转换成某种视觉显示,它不应该直接控制应用程序的其他部分 UI,弄乱后栈等
理想情况下,您应该有某种可以在单击项目时更新的侦听器。就是这样,适配器只是说“嘿,这个被点击了”,也许会提供一些关于它的细节,然后由听众(如果有的话)决定如何处理。
最好使用的可能是 ViewModel
- 将其传递给适配器,有一个可以设置的 currentItem
LiveData
值,然后其他组件可以 observe
该值并对其做出反应。适配器不需要知道他们在做什么。
快速而肮脏的方法是在父 Activity
上有一个方法,例如 onAnimalItemClicked()
,将其传递给 Adapter
,并在需要时调用该方法到。您需要使用特定的 Activity class 除非您为 Activity 实现的方法创建接口。这并不理想(并且在保持对 Activity 之类的引用时始终要注意内存泄漏)但它完成了工作