咱们好,本篇文章给咱们分享下官方开源库activity-ktx供给的几个有用的小东西,期望能对你有所协助,本篇文章为咱们带来ComponentDialog
的介绍。
当前根据如下版别进行剖析:
dependencies {
implementation "androidx.activity:activity-ktx:1.8.0"
}
ComponentDialog—集各种特性于一体的大成Dialog
假如经常运用Android Jetpack相关组件的开发者,相信对下面的几个接口非常了解:
-
LifecycleOwner
:供给组件可观察的生命周期 -
OnBackPressedDispatcherOwner
:供给体系回来按钮事情的监听; -
SavedStateRegistryOwner
:保存因装备发生更改界面毁掉重建前的相关数据,重建后可以重新获取
凭借于官方的支持,上面这些接口特性在Activity
、Fragment
中都有表现,但是咱们想一想,Dialog
有这个待遇吗?哈哈,这不ComponentDialog
组件就应运而生了。
open class ComponentDialog @JvmOverloads constructor(
context: Context,
@StyleRes themeResId: Int = 0
) : Dialog(context, themeResId),
LifecycleOwner,
OnBackPressedDispatcherOwner,
SavedStateRegistryOwner {
//...
}
ComponentDialog实现了上面的三个接口,所以具有了三个接口对应的才能,接下来咱们来分别演示下。
先自定义一个ComponentDialog类:
class CustomComponentDialog(mContext: Context): ComponentDialog(mContext) {
override fun onSaveInstanceState(): Bundle {
return super.onSaveInstanceState()
}
}
1. LifecycleOwner才能
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val customComponentDialog = CustomComponentDialog(this)
customComponentDialog.show()
customComponentDialog.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
}
})
}
假如是咱们直接之前运用Dialog,为了监听Dialog的show和dismiss等场景,都会自动调用办法比方setOnDismissListener
和setOnShowListener
等设置监听器,这样就会导致一个安全隐患:Dialog持有了外部类引证,而这个外部类引证会被对象池中的Message持有,假如这个Message和HanderThread音讯队列中的Message同享,那这就发生内存走漏的安全隐患。DialogFragment也相同存在这样的安全隐患。
这个内存走漏的安全隐患就不再这儿进行剖析了,咱们可以这两篇文章了解学习一番:
Android开发:Message 引发的 DialogFragment 内存走漏剖析与解决方案
而现在ComponentDialog供给了Lifecycle的才能,咱们就可以通过增加观察者的办法来监听Dialog的show和dismiss,而不会发生一点点内存走漏的安全隐患,咱们可以定心食用。
不过这儿有两点需求注意的当地:
-
lifecycle的resume办法执行是早于监听器
setOnShowListener(DialogInterface.OnShowListener)
回调时机,其凭借ComponentDialog#onStart()
办法告诉观察者Resume事情发生 -
lifecycle的destory办法执行相同早于监听器
setOnDismissListener(DialogInterface#OnDismissListener)
回调时机,其凭借ComponentDialog#onStop
告诉观察者onDestory事情发生
2. OnBackPressedDispatcherOwner才能
供给监听体系回来按键点击事情的才能
customComponentDialog.onBackPressedDispatcher.addCallback {
Log.i("TAG", "onCreate: onBackPressedDispatcher")
isEnable = false
}
不过这个东西可要善用,比方假如上面代码中没有关键的isEnable = false
,那么相当于体系回来按钮事情就被这个Dialog给拦截了,其他的当地back事情都无法响应了。
所以当处理完Dialog的back监听事情后,需求自动设置isEnable = false
才能保证该体系回来键点击事情可以正常流转,当然了详细要视业务场景而定。
详细的使用场景也会有不少,比方当前正在显示一个供给编辑才能的Dialog,先设置个onBack监听,在点击体系回来键时,提示用户是否要保存草稿等相似功能。相比较直接重写onKeyUp、onBackPress等体系办法,设置onBackPressedCallback的办法运用起来愈加灵敏方便。
顺便给咱们推荐一个好用的扩展办法,这样增加onback监听就十分方便了:
3. SavedStateRegistryOwner才能
这个相似于有点相似于ViewModel,可以保存状况数据,比方当界面由于旋转、换肤等此原因导致Activity重建时,就可以将之前的数据进行重现,和ViewModel的才能有点像。
customComponentDialog.savedStateRegistry.registerSavedStateProvider("key") {
Bundle().apply {
putInt("count", 100)
}
}
指定一个key,以及要存储的数据即可,终究这个伴随着Dialog#onSaveInstanceState()
一同存储。
不过这个效果感觉运用场景不大,并且存在运用约束,并且Dialog依赖Activity的context,直接运用Activity的ViewModel保存数据也能实现Dialog状况数据的保存以及恢复。
当然了仁者见仁,智者见智,对于Dialog运用的这个特性再这儿就不再提了。
历史文章
一文洞彻:Application为啥不能作为Dialog的context?
这篇文章咱们可以看看哈,也是运用Dialog时需求了解的一个知识点,带你了解Dialog的context一定不能是Application吗?只能是Activity吗?