当前位置:  开发笔记 > Android > 正文

DialogFragment中的Kotlin合成和自定义布局

如何解决《DialogFragment中的Kotlin合成和自定义布局》经验,为你挑选了2个好方法。

假设我有这样的布局:












我在DialogFragment中使用它:

class DepartmentChoiceDialog : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val builder = AlertDialog.Builder(activity)
        builder.setTitle(R.string.choose_or_create_dep)
            .setView(R.layout.department_chooser_dialog)
            .setNegativeButton(android.R.string.cancel, { d, i ->
                d.cancel()
            })
        return builder.create()
    }
}

如果我使用合成来引用小部件:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    dep_list.layoutManager = LinearLayoutManager(activity)
    dep_list.itemAnimator = DefaultItemAnimator()
    dep_list.setHasFixedSize(true)
}

我在运行时遇到这个错误:

java.lang.NullPointerException:尝试在MyDialog上的空对象引用上调用虚拟方法'android.view.View android.view.View.findViewById(int)'._ $ _ findCachedViewById(DepartmentChoiceDialog.kt:0)

我不明白如何在DialogFragment案例中使用合成.它在Fragment和Activity中工作正常.



1> Sabaat Ahmad..:

我发现了一种适用于自定义对话框的方法.

class ServerPickerDialogFragment: AppCompatDialogFragment() 
{
  // Save your custom view at the class level
  lateinit var customView: View;
  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                            savedInstanceState: Bundle?): View? 
  {
       // Simply return the already inflated custom view
       return customView
  }

  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
      // Inflate your view here
      customView = context!!.layoutInflater.inflate(R.layout.dialog_server_picker, null) 
      // Create Alert Dialog with your custom view
      return AlertDialog.Builder(context!!)
             .setTitle(R.string.server_picker_dialog_title)
             .setView(customView)
             .setNegativeButton(android.R.string.cancel, null)
             .create()
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
  {
    super.onViewCreated(view, savedInstanceState)
    // Perform remaining operations here. No null issues.
    rbgSelectType.setOnCheckedChangeListener({ _, checkedId ->
      if(checkedId == R.id.rbSelectFromList) {
             // XYZ
      } else {
             // ABC
      }
    })
  }
}



2> SUPERCILEX..:

看起来默认情况下不支持此功能,但我发现最简单的方法就是这样.在基础对话框类中:

protected abstract val containerView: View

override fun getView() = containerView

在子类中:

override val containerView by unsafeLazy {
    View.inflate(context, R.layout.dialog_team_details, null) as ViewGroup
}

然后,您可以像往常一样使用合成视图,并将其containerView用作对话框的视图.


我使用Leak Canary,却什么都没注意到。而且,仅考虑它,就不会出现内存泄漏,因为该视图与上下文类的实例相关联,并且将在配置更改中随其死亡。
推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有