【问题标题】:Kotlin: Fragment not attached, Unable to instantiate fragment calling fragment const caused exceptionKotlin:片段未附加,无法实例化片段调用片段常量导致异常
【发布时间】:2021-07-07 20:04:28
【问题描述】:

我正在尝试将 childFragmentManager 从片段传递到适配器。当前片段是从不同的片段而不是活动中调用的。

片段类有一个值

class DisplaySchoolFrag : BaseFragment<binding, DisplaySchoolViewModel>{
...

private val adapter = DisplaySchoolAdapter(childFragmentManager)

在适配器中,我只有 childFrag 的 const 声明,暂时没有其他用途。

class DisplaySchoolAdapter(childFrag: FragmentManager) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

我需要适配器内部的 childFragmentManager,因为在适配器类内部有一个通向底部片断的按钮。

FragmentHostCallback<?> mhost
getChildFrar(){
if (this.mHost == null) {
            throw new IllegalStateException("Fragment " + this + " has not been attached yet.");

而这一行导致 Fragment 未附加,无法实例化 Fragment 调用 Fragment const 导致异常

我试过了

lateinit var childFrag : FragmentManager


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
         childFrag = childFragmentManager
        return super.onCreateView(inflater, container, savedInstanceState)
    }

并将 childFrag 传递给 DisplaySchoolAdapter(childFrag) 声明仍然出现错误。

【问题讨论】:

  • 你能展示更多你的适配器类吗?你分享的只是一些随机的不可编译的代码,所以很难说它有什么问题。快速而肮脏的解决方法是使适配器属性变得懒惰,但我认为深入了解问题会更好(使您的适配器更健壮)。 private val adapter: DisplaySchoolAdapter by lazy { DisplaySchoolAdapter(childFragmentManager) }
  • 我的两分钱是您应该将 lambda 传递到您的适配器并覆盖 onClick 属性并调用 lambda。然后在你的片段中,你可以得到 childFragmentManager 并去任何你需要去的地方
  • @Rafa,是的,使用监听器方法会更好地分离关注点。让 Fragment 决定按钮点击应该做什么。

标签: java android kotlin android-fragments


【解决方案1】:

您应该将回调传递给DisplaySchoolAdapter,并覆盖单个项目的setOnClickListener 侦听器并调用回调。

class DisplaySchoolAdapter(lambdaToBeInvoked: () -> Unit): RecyclerView.Adapter<SomeViewHolder>() {

   ... set up your adapter

   override fun onBindViewHolder(holder: SomeViewHolder, position: Int) {
     val item = items[position]
     holder.bind(item)
     holder.itemView.setOnClickListener { lambdaToBeInvoked() }
   }
}

您可以在适配器的其余部分填写实现细节,但onBindViewHolder 是您调用回调的地方。如果您需要向其中传递任何参数,请随时在您的实现中添加这些参数。

然后在您的片段中,当您实例化您的适配器时,您将传递您希望您的 childFragment 执行的操作。

class YourFragment: FragmentActivity() {
 
    override onCreate() {
         
         val adapter = DisplaySchoolAdapter {
              // have your childFragment navigate to somewhere
         }

         recyclerView.adapter = adapter
         recyclerView.layoutManager = LinearLayoutManager()
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多