首页 > 解决方案 > 有没有办法使用 Kotlin Anko Alertdialog 来处理屏幕旋转变化?

问题描述

使用 Anko 库非常简单,但是当我旋转屏幕时,我的对话框消失了。避免这种情况的唯一方法是使用DialogFragment()with 方法的子级show(fm, TAG)

所以我们需要重写onCreateDialog(savedInstanceState: Bundle?): Dialog返回Dialog实例的方法。但是 Anko 的alert{ }.build()返回DialogInterface实例

那么,有没有办法在这种情况下使用 anko 呢?

alert {
        message = "Message"                   
        positiveButton("OK") {
            //stuff
        }
        negativeButton("NOT OK") {
            //stuff
        }
}.show()

编辑

所以,这就是我所做的。我创建了抽象BaseDialogFragment

abstract class BaseDialogFragment : DialogFragment() {

    abstract val ankoAlert: AlertBuilder<DialogInterface>

    protected var dialogListener: DialogListener? = null

    protected val vm by lazy {
        act.getViewModel(DialogViewModel::class)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        dialogListener = parentFragment as? DialogListener
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
            (ankoAlert.build() as? Dialog)
                    ?: error("Anko DialogInterface is no longer backed by Android Dialog")
}

然后我创建了一些对话框,如下所示:

class MyDialogFragment : BaseDialogFragment() {

    companion object {
        fun create() = MyDialogFragment ()
    }

    override val ankoAlert: AlertBuilder<DialogInterface>
        get() = alert {
            negativeButton(R.string.app_canceled) {
                dialogListener?.onDismiss?.invoke()
            }
            customView = createCustomView(vm.data)
        }

    fun createCustomView(data: Data): View {
        //returning view
    }
}

我的 DialogListener 也是这样的:

interface DialogListener {

    var onDismiss: () -> Unit

    val onClick: (Data) -> Unit

    var onPostClick: (Data) -> Unit

}

最后,在父片段中我们可以使用:

MyDialogFragment.create().show(childFragmentManager, MyDialogFragment::class.java.simpleName)

希望它会帮助某人。

标签: androidkotlinandroid-alertdialoganko

解决方案


从 Android 文档中,Dialog实现DialogInterface. 因此,所有已知的Dialog包含子类都AlertDialog实现了该接口。

您可以转换并从构建返回结果,如下所示:

return alert {
    message = "Message"                   
    positiveButton("OK") {
        //stuff
    }
    negativeButton("NOT OK") {
        //stuff
    }
}.build() as Dialog

这会起作用,但如果 Anko 改变了它的实现,你会得到一个ClassCastException. 要获得更清晰的错误,您可以使用以下内容。

val dialogInterface = alert {
    message = "Message"                   
    positiveButton("OK") {
        //stuff
    }
    negativeButton("NOT OK") {
        //stuff
    }
}.build()
return (dialogInterface as? Dialog) ?: error("Anko DialogInterface is no longer backed by Android Dialog")

这会给你一个更明确的错误,但很可能不需要。


推荐阅读