Android Dialog 源码研究
来源:互联网 发布:淘宝网衬衫连衣裙女 编辑:程序博客网 时间:2024/05/24 05:20
Android Dialog 源码研究
在阅读Dialog源代码之前,我给自己提出了4个问题,带着这4个问题的疑问,我才开始看源码,这样的好处能让阅读中有了侧重点,往往能更快的理解某些代码的意图,这也正是为什么总说提出问题本身,要比解决问题困难
。
我下面要思考的4个问题是:
- Dialog到底是什么东西?
- Dialog到底是如何被显示到屏幕上?
- Dialog的构建,有哪些类参与,都有什么作用?
- Dialog的主要API,是如何让Dialog发生变化的?
首先,我们先得搞清楚Dialog的继承体系,整体把握下Dialog的设计结构。下图即为Dialog的继承体系树结构:
对Dialog有了整体认识之后,我们带着上面4个问题来阅读源码,并从中找到问题的答案。当把所有问题都解决掉之后,Dialog的源码也基本上都看懂了,对之后的自定义Dialog有很大帮助。
Dialog本质上是什么?
先看Dialog类的源码的构造函数,发现不同的构造内部最后都会调用3个参数的构造Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper)
。
我们来看下,该构造中形参的作用,第一个参数上下文,就不用解释啦。
1.themeResId
a style resource describing the theme to use for the window, or 0 to use the default dialog theme。
在源码中,关于themeResId的解释如上,说明该入参设置了window的主题,看到这里我好像明白了Dialog到底是个什么玩意,我们再看下源码是如何使用这个参数的:
其中,createContextThemeWrapper
在源码中是固定值true
,因此这个构造的if语句一定会被执行,我们可以看到context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
表示默认情况下会自动引用系统主题。
很显然,通过重写某些参数会创建自定义样式的Dialog,请读者自行测试。
2.createContextThemeWrapper
由构造直接传入true
值,没什么好讲的。
3.Window
在前面分析的构造方法中,后面还有一小段代码非常重要,它传达了非常强烈的信息:Dialog其实本质上就是一个Window。
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);final Window w = new PhoneWindow(mContext);mWindow = w;w.setCallback(this);w.setOnWindowDismissedCallback(this);w.setWindowManager(mWindowManager, null, null);w.setGravity(Gravity.CENTER);mListenersHandler = new ListenersHandler(this);
注意到,这里new
出一个PhoneWindow
对象并赋值给Dialog的成员变量mWinodw
。这里,设置了3个监听器,从而有了上面的Dialog继承体系结构,当看到w.setGravity(Gravity.CENTER);
我立刻明白了,原来这个PhoneWindow
其实就是我们的Dialog,这也解释了为什么Dialog为什么会显示在屏幕的正中间。
当然,现在直接说Dialog就是Window可能你还不信,那接下来问题2的答案就让你确信无疑啦。
Dialog到底是怎样被显示到屏幕或移除的?
我们已经知道,要想Dialog显示出来,就应该调用show()
方法,而移除时要调用dismiss()
。
1.show( )
从上面部分代码来看,show( )
方法还真做了不少事,而onStart( )
只有一行代码,可以复写来进行一些初始化工作。
其中,最引人注目的是mDecor
对象,前面说过mWinodw
就是new
出来的PhoneWindow
,根据Window
类的官方描述:
Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.The only existing implementation of this abstract class is android.view.PhoneWindow, which you should instantiate when needing a Window.
mDecor
就是获取Window的View形式下的对象。这样可以方便WindowManager
通过方法addView(...)
把内容绘制到Window上,这样就完成Dialog的显示,当然具体是如何被添加绘制到屏幕上,这牵涉到底层UI绘制原理,不在本文分析范围内。
2.dismiss( )
下面,我们再来看看Dialog如何从屏幕上移除的,主要看方法dismiss()
的实现。
因为,在dismiss()
中增加了线程是否为主线程的条件判断,因此是可以在任何线程中调用dismiss()
来移除Dialog。
综上所诉,我们可以得出:其实Dialog就是一个Window,显示与移除都是通过窗口管理器WindowManager
完成的,如果需要完全自定义Dialog的内容,则需要通过Window设置其ContentView
,再通过Window.getDecorView()
获取到这个View,最后通过WindowManager
进行添加与移除。
未完待续~~~
- Android Dialog 源码研究
- android源码解析--Dialog
- Android源码解析之Dialog
- Android--Dialog对话框动画源码
- Android中Dialog源码解析
- Android源码研究Tips
- android源码的研究
- Android源码研究
- Android源码的研究
- android RIL源码研究
- Android系统源码研究
- Android Contacts源码研究心得
- Android UI结构源码研究
- android ViewPageIndicator指示器源码研究
- jquery dialog的研究
- Android RIL源码研究笔记 の ril_event
- Android Settings 源码研究---导入eclipse
- Android Launcher源码研究(一) 基本结构
- Java-Socket
- 卖火柴的小女孩
- 骑士精神
- 官方推荐的Dialog——DialogFragment
- GreenDao使用说明(一)
- Android Dialog 源码研究
- HTML5学习04-HTML5列表、快和布局
- FTP 编写 3:同时为多个客户端服务(多线程)
- linux环境变量
- 微信支付和连连支付
- 设置状态栏颜色
- Oracle卸载
- 判断是否是图片,java实现
- mysql数据库表删除的奥秘