Android系统封装了AlertDialog,用来给我们使用。我们可以通过

AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("Title").setMessage("message").create().show();
复制代码

这个其实就是典型的Builder设计模式,通过封装复杂的dialog对象,将组建和构建分离,当用户使用的时候可以直接调用组建,并最后创建出Dialog对象。

通过Dialog源码的分析,我们能够更好的了解Builder设计模式。

public class AlertDialog extends Dialog implements DialogInterface {private AlertController mAlert;AlertDialog(Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {super(context, createContextThemeWrapper ? resolveDialogTheme(context, themeResId) : 0,createContextThemeWrapper);mWindow.alwaysReadCloseOnTouchAttr();mAlert = new AlertController(getContext(), this, getWindow());}@Overridepublic void setTitle(CharSequence title) {super.setTitle(title);mAlert.setTitle(title);}public static class Builder {public Builder(Context context, int themeResId) {P = new AlertController.AlertParams(new ContextThemeWrapper(context, resolveDialogTheme(context, themeResId)));}public Builder setTitle(@StringRes int titleId) {P.mTitle = P.mContext.getText(titleId);return this;}public AlertDialog create() {// Context has already been wrapped with the appropriate theme.final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);P.apply(dialog.mAlert);dialog.setCancelable(P.mCancelable);if (P.mCancelable) {dialog.setCanceledOnTouchOutside(true);}dialog.setOnCancelListener(P.mOnCancelListener);dialog.setOnDismissListener(P.mOnDismissListener);if (P.mOnKeyListener != null) {dialog.setOnKeyListener(P.mOnKeyListener);}return dialog;}public AlertDialog show() {final AlertDialog dialog = create();dialog.show();return dialog;}}
}
复制代码

通过上面的代码我们可以看到,创建AlertDialog.Build的时候会创建一个AlertController.AlertParams对象,这个对象里面封装了所有的Dialog的属性,并且在调用Builder的类似于setTitle方法的时候会将参数赋值给AlertParams,当所有的组件的属性赋值好之后,就调用create()方法,这个方法里面就创建出AlertDialog对象,并调用P.apply(dialog.mAlert)方法,将AlertDialog构造函数创建出来的AlertController对象传递给P:

public void apply(AlertController dialog) {if (mCustomTitleView != null) {dialog.setCustomTitle(mCustomTitleView);} else {if (mTitle != null) {dialog.setTitle(mTitle);}if (mIcon != null) {dialog.setIcon(mIcon);}if (mIconId != 0) {dialog.setIcon(mIconId);}if (mIconAttrId != 0) {dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));}}// 代码省略
}
复制代码

在apply方法中,可以发现只是把AlertParams中的参数设置到AlertController中,当我们调用create方法的时候,就是讲AlertDialog对象的组件组装起来,当我调用show的时候就会调用dialog的show方法:

public void show() {// 如果已经在显示状态,returnif (mShowing) {if (mDecor != null) {if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);}mDecor.setVisibility(View.VISIBLE);}return;}mCanceled = false;if (!mCreated) {dispatchOnCreate(null);}onStart();// 获取DecorViewmDecor = mWindow.getDecorView();// 获取布局参数WindowManager.LayoutParams l = mWindow.getAttributes();if ((l.softInputMode& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {WindowManager.LayoutParams nl = new WindowManager.LayoutParams();nl.copyFrom(l);nl.softInputMode |=WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;l = nl;}// 将decorView添加到WindowManager中mWindowManager.addView(mDecor, l);mShowing = true;// 发送一个现实Dialog的消息sendShowMessage();
}
复制代码

在show方法中:

  1. 通过diapatchOnCreate方法,调用Dialog的onCreate方法,并最终调用installContent方法。

    public void installContent() {/* We use a custom title so never request a window title */mWindow.requestFeature(Window.FEATURE_NO_TITLE);// 设置窗口的视图int contentView = selectContentView();mWindow.setContentView(contentView);setupView();setupDecor();
    }
    private int selectContentView() {if (mButtonPanelSideLayout == 0) {return mAlertDialogLayout;}if (mButtonPanelLayoutHint == AlertDialog.LAYOUT_HINT_SIDE) {return mButtonPanelSideLayout;}// TODO: use layout hint side for long messages/listsreturn mAlertDialogLayout;
    }
    复制代码

    而我们可以看到在调用selectContentView的时候,会去获取mButtonPanelSideLayout视图,并通过WindowManager的setContentView方法来将视图加载。

    public AlertController(Context context, DialogInterface di, Window window) {final TypedArray a = context.obtainStyledAttributes(null,R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);// 获取视图mAlertDialogLayout = a.getResourceId(R.styleable.AlertDialog_layout, R.layout.alert_dialog);a.recycle();
    }
    复制代码

    再通过setupView方法初始化AlertDialog布局中的各个部分

  2. 调用AlertDialog的onStart方法

  3. 最后将DecorView添加到WindowManager中

【Android源码】AlertDialog 源码分析相关推荐

  1. Android 系统(78)---《android framework常用api源码分析》之 app应用安装流程

    <android framework常用api源码分析>之 app应用安装流程 <android framework常用api源码分析>android生态在中国已经发展非常庞大 ...

  2. Android Camera 系统架构源码分析

    Android Camera 系统架构源码分析(1)---->Camera的初始化 Android Camera 系统架构源码分析(2)---->Camera的startPreview和s ...

  3. Android 8.0系统源码分析--开篇

    个人分类: Android框架总结Android源码解析android framework 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sinat ...

  4. Android+上百实例源码分析以及开源分析+集合打包

    1.360新版特性界面源代码 实现了360新版特性界面的效果,主要涉及到Qt的一些事件处理与自定义控件.但源码好像是c++. 2.aidl跨进程调用 服务端onBind暴露,然后客户端bindServ ...

  5. Android 11.0 Settings源码分析 - 主界面加载

    Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...

  6. Android录音下————AudioRecord源码分析

    Android录音下----AudioRecord源码分析 文章目录 Android录音下----AudioRecord源码分析 一.概述 1.主要分析点 2.储备知识 二.getMinBufferS ...

  7. Android WIFI调试助手源码分析

    **WIFI调试助手源码(支持十六进制和ACSII发送与接收) 客户端(我自己修改的工程文件,支持十六制的接收与发送,主要是通信协议,代码简单,可轻松改造为上位机) ** 分为操作分析和代码分析. 1 ...

  8. Android上百实例源码分析以及开源分析集合打包

    感谢网友banketree的收集,压缩包的内容如下: 1.360新版特性界面源代码 实现了360新版特性界面的效果,主要涉及到Qt的一些事件处理与自定义控件.但源码好像是c++. 2.aidl跨进程调 ...

  9. Android 8.0系统源码分析--Camera processCaptureResult结果回传源码分析

    相机,从上到下概览一下,真是太大了,上面的APP->Framework->CameraServer->CameraHAL,HAL进程中Pipeline.接各种算法的Node.再往下的 ...

  10. Android 双开沙箱 VirtualApp 源码分析(一)

    最近发现了一个非常好的开源项目,基本实现了一个 Android 上的沙箱环境,不过应用场景最多的还是应用双开. VA github: https://github.com/asLody/Virtual ...

最新文章

  1. Matlab数据的可视化 -- 图形格式的设置
  2. OpenStack看到中国“钱”景
  3. 右手螺旋判断磁感应强度方向_高考丨电磁感应丨感应电动势
  4. 小微企业——客户借款原因分析
  5. JavaScript学习(六十)—JSON
  6. python求立方尾不变_蓝桥杯—立方尾不变,有些数字的立方的末尾正好是该数字本身...
  7. ftp和http转参数的使用(转)
  8. Android 蓝牙键盘快捷键
  9. %02x与%2x 区别
  10. 码支付源码完整版-安装环境配置
  11. 面向对象,面向对象的优点
  12. (转)Ogre 天龙八部 GridInfo文件格式说明(正确版)
  13. 如何通俗理解并快速写出麦克斯韦方程组?
  14. 如何利用laragon框架制作一个简单的应用?
  15. 基于Singer混沌映射的麻雀搜索算法-附代码
  16. CentOS7快速搭建DNS中转服务器
  17. 生化实验技术——酵母双杂交
  18. 路径规划算法学习Day5
  19. Django项目使用wangeditor方法
  20. 大学英语4级该如何有效的学习?

热门文章

  1. get post put delete 区别_GET 和 POST 的区别?
  2. linux下redis安装教程,linux下安装配置redis图文详解
  3. seo说_百度指数看世间沉浮_如何快速排名-互点快速排名_网站关键词排名常见问题 - 搜狗快速排名...
  4. jquery实现表格拖拽排序
  5. mysql快速迁移数据sql_使用Navicat Premium工具快速迁移数据方法 适用于mysql及mssql数据库...
  6. bios设置 联想m8000t_联想怎样设置双显卡模式 联想设置双显卡模式方法【详解】...
  7. client软件怎么卸载 nac_如何彻底卸载在 Mac 上安装的一个软件?
  8. 范德蒙德矩阵在MATLAB中怎么表示,Python 之 Python与MATLAB 矩阵操作总结
  9. springboot整合springSecurity使用
  10. Java设计模式(代理模式-模板方法模式-命令模式)