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?太难了

相关推荐
松仔log12 小时前
Java中级——组合和继承
android·java·开发语言
我命由我1234515 小时前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian23316 小时前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_9557596216 小时前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
余衫马16 小时前
2026最新版!Android Studio 极速安装与配置指南
android·ide·android studio
AFinalStone16 小时前
Android 7系统异常问题排查(五)Framework层(下)—System Server崩溃
android·tombstone·系统异常
AFinalStone16 小时前
Android 7系统异常问题排查(八)系统追踪—Trace机制与性能诊断
android·系统异常
极客猴子20 小时前
Android录音转写频繁卡顿?多款APP长时间会议场景稳定性实测
android·人工智能·智能手机·飞书
Kapaseker20 小时前
Boolean 变量到底该怎么命名?
android·kotlin
AFinalStone20 小时前
Android 7系统异常问题排查(六)应用异常(上)—ANR机制全解
android·系统异常