Android Dialog 插槽模式:用一套壳统一全应用的弹窗风格

把弹窗拆成"固定骨架 + 可替换内容插槽",新弹窗只要提供一个布局,风格自动统一。

前言

一个 App 里弹窗特别多:底部选择器、确认框、输入框、信息展示......如果每个弹窗都从零写一个布局、各自调样式,结果就是------颜色深浅不一、圆角大小不一、标题字体不一,看起来像三个团队做的。

这篇文章讲一种插槽模式:先定义一份统一的弹窗骨架(标题栏 + 内容区 + 可选的操作栏),内容区留一个"插槽",不同弹窗只需要往插槽里塞各自的布局,风格就天然统一了。

一、痛点:每个弹窗各写各的

最原始的做法是每个弹窗一个独立的布局文件,自己管标题、自己管按钮、自己设背景圆角:

xml 复制代码
<!-- 弹窗 A 的布局 -->
<LinearLayout ...>
   <TextView android:text="提示" .../>
   <TextView android:text="确认删除?" .../>
   <Button android:text="确定" .../>
</LinearLayout>

弹窗 A、B、C 各自这样写,标题样式、按钮样式、圆角完全靠每个开发者"记得保持统一"。一旦有人改了主题色,所有弹窗要挨个改。插槽模式要解决的就是这个"重复 + 不统一"。

二、骨架:一份统一布局 + 一个内容插槽

定义一份"通用弹窗骨架"布局,结构固定:

复制代码
标题栏(可隐藏)
────────────
内容区(插槽)
────────────
操作栏(可隐藏:确定/取消按钮)

在代码里,弹窗基类暴露两个"槽位"方法:一个提供内容布局,一个提供标题栏布局(可选)。子类只需重写这些方法,往槽位里放自己的东西:

kotlin 复制代码
abstract class BaseBottomDialog : BottomSheetDialogFragment() {

    // 子类重写:返回自己的内容布局
    protected abstract fun contentView(parent: ViewGroup): View

    // 子类可选重写:返回标题栏布局(默认不显示)
    protected open fun titleView(parent: ViewGroup): View? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        // 加载统一骨架
        val root = inflater.inflate(R.layout.dialog_skeleton, container, false)

        // 往插槽里填内容
        val contentSlot = root.findViewById<FrameLayout>(R.id.content_slot)
        contentSlot.addView(contentView(contentSlot))

        // 可选标题
        val titleSlot = root.findViewById<FrameLayout>(R.id.title_slot)
        titleView(contentSlot)?.let { titleSlot.addView(it) }

        return root
    }
}

骨架布局里,标题栏和操作栏默认 gone(隐藏),子类需要时才显示。所有弹窗共用这份骨架,所以圆角、背景、标题样式只有一份,改一次全生效。

三、内容插槽:子类只写"中间那块"

具体弹窗子类变得非常轻,只需重写 contentView 提供中间内容:

kotlin 复制代码
class ConfirmDeleteDialog(
    private val onConfirm: () -> Unit
) : BaseBottomDialog() {

    override fun contentView(parent: ViewGroup): View {
        return inflater(parent).inflate(R.layout.content_confirm, parent, false)
    }

    override fun onConfirmClicked() {
        onConfirm()
        dismiss()
    }
}

要做一个新弹窗,只需要:新建一个内容布局 + 继承骨架 + 重写一个方法。不需要关心标题、按钮、圆角长什么样,这些全在骨架里定好了。

四、操作栏:确定/取消的复用

确定/取消按钮也在骨架里,通过回调让子类挂接自己的逻辑:

kotlin 复制代码
// 骨架里提供统一的确定/取消回调
interface ActionListener {
    fun onConfirm()
    fun onCancel() {}
}

子类实现 onConfirm/onCancel,骨架负责绑定按钮点击和默认样式。于是所有弹窗的按钮都是同一个样式、同一个间距,点按反馈也统一。

结论

  • 弹窗重复 + 不统一的根因是每个弹窗各自写布局,插槽模式把"骨架"和"内容"分离。
  • 统一骨架(标题 + 内容插槽 + 操作栏)一份定义、处处复用,改主题只需改骨架。
  • 子类只需重写"内容插槽"方法,新弹窗成本 = 一个新布局 + 一个继承类。
  • 操作栏用统一回调挂接,按钮样式、点击反馈全局一致。
  • 插槽/模板模式的本质是把变化的(内容)和不变的(骨架)拆开,这套思路也适用于统一的空页面、列表项、引导页。

你项目里弹窗风格不统一的问题,是用插槽模式还是别的方案解决的?欢迎在评论区聊聊你的做法。

关键词标签 :#Android #Dialog #BottomSheetDialog #插槽模式 #弹窗 #统一风格 #模板模式 #Kotlin

相关推荐
huanbailu1 小时前
Qt 跨线程信号槽:connect 返回 true 但槽函数不执行的坑
开发语言·c++·qt·信号槽·跨线程·元类型
u0111026751 小时前
工具页案例图如何编写 alt让图片说明与处理场景对应
java·前端·javascript·图像处理·人工智能·算法·ai作画
ZealSinger1 小时前
Go slog生产落地LevelVar与共存
开发语言·后端·golang·go
码上有光1 小时前
Linux:进程间通信——匿名管道通信、命名管道通信
android·java·linux·linux通信·匿名通信·命名通信
落魄实习生1 小时前
Agent Scope Java 2.x 系列【11】AgentState 与状态存储
java·开发语言·ai
HEJOO91 小时前
C++ 虚函数表(vtable)深度解析
开发语言·c++
老王爱玩车1 小时前
深入理解指针5
c语言·开发语言·学习
丹宇码农2 小时前
Go 与 Python 协程(Coroutine)对比演示项目
开发语言·python·golang
Ivanqhz2 小时前
干涉图着色
java·服务器·网络·数据库·人工智能·深度学习