ComponentDialog—集各种特性于一体的大成Dialog

大家好,本篇文章给大家分享下官方开源库activity-ktx提供的几个有用的小工具,希望能对你有所帮助,本篇文章为大家带来ComponentDialog的介绍。

当前基于如下版本进行分析:

groovy 复制代码
dependencies {
    implementation "androidx.activity:activity-ktx:1.8.0"
}

ComponentDialog---集各种特性于一体的大成Dialog

如果经常使用Android Jetpack相关组件的开发者,相信对下面的几个接口非常了解:

  • LifecycleOwner:提供组件可观察的生命周期
  • OnBackPressedDispatcherOwner:提供系统返回按钮事件的监听;
  • SavedStateRegistryOwner:保存因配置发生更改界面销毁重建前的相关数据,重建后能够重新获取

借助于官方的支持,上面这些接口特性在ActivityFragment中都有体现,但是大家想一想,Dialog有这个待遇吗?哈哈,这不ComponentDialog组件就应运而生了。

kotlin 复制代码
open class ComponentDialog @JvmOverloads constructor(
    context: Context,
    @StyleRes themeResId: Int = 0
) : Dialog(context, themeResId),
    LifecycleOwner,
    OnBackPressedDispatcherOwner,
    SavedStateRegistryOwner {
        //...
}

ComponentDialog实现了上面的三个接口,所以拥有了三个接口对应的能力,接下来咱们来分别演示下。

先自定义一个ComponentDialog类:

kotlin 复制代码
class CustomComponentDialog(mContext: Context): ComponentDialog(mContext) {

    override fun onSaveInstanceState(): Bundle {
        return super.onSaveInstanceState()
    }
}

1. LifecycleOwner能力

kotlin 复制代码
    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等场景,都会主动调用方法诸如setOnDismissListenersetOnShowListener等设置监听器,这样就会导致一个安全隐患:Dialog持有了外部类引用,而这个外部类引用会被对象池中的Message持有,如果这个Message和HanderThread消息队列中的Message共享,那这就产生内存泄漏的安全隐患。DialogFragment也同样存在这样的安全隐患。

这个内存泄漏的安全隐患就不再这里进行分析了,大家可以这两篇文章了解学习一番:

Android开发:Message 引发的 DialogFragment 内存泄漏分析与解决方案

使用Dialog可能引起的内存泄漏

而现在ComponentDialog提供了Lifecycle的能力,我们就可以通过添加观察者的方式来监听Dialog的show和dismiss,而不会产生丝毫内存泄漏的安全隐患,大家可以放心食用。

不过这里有两点需要注意的地方:

  1. lifecycle的resume方法执行是早于监听器setOnShowListener(DialogInterface.OnShowListener)回调时机,其借助ComponentDialog#onStart()方法通知观察者Resume事件发生

  2. lifecycle的destory方法执行同样早于监听器setOnDismissListener(DialogInterface#OnDismissListener)回调时机,其借助ComponentDialog#onStop通知观察者onDestory事件产生

2. OnBackPressedDispatcherOwner能力

提供监听系统返回按键点击事件的能力

arduino 复制代码
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的能力有点像。

scss 复制代码
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吗?

子线程刷UI->Barrier屏障->主线程装死->应用GG?太难了

相关推荐
周全全7 分钟前
MySQL报错解决:The user specified as a definer (‘root‘@‘%‘) does not exist
android·数据库·mysql
- 羊羊不超越 -43 分钟前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
wk灬丨1 小时前
Android Kotlin Flow 冷流 热流
android·kotlin·flow
千雅爸爸1 小时前
Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)
android
晨曦_子画2 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
孤客网络科技工作室2 小时前
AJAX 全面教程:从基础到高级
android·ajax·okhttp
Mr Lee_4 小时前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野4 小时前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&4 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin