1.前言
在android当中对于UI体系当中往往我们会在绘制UI的时候碰到各种各样的问题而不知道从何解决, 也有时需要开发更改自定义组件时,需要做自己的调整,或者是实现某个自定义特效时的思路不明确,因此了解UI绘制流程及原理是十分必要的,本文就UI绘制流程之前的相关知识进行简单的分析和梳理,便于后续进一步了解UI绘制原理
2.View是如何添加到屏幕窗口上的
要弄清楚UI绘制流程和原理,我们首先要了解的就是View是如何被添加到屏幕窗口上的。带着这个问题我们来进行源码分析,关于界面的展示,立马浮现在脑海的就是这样一段代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
通过传入布局资源ID,setContentView方法又做了什么事情呢?经过一系列线索最终找到了的位置也就是Window的唯一实现类PhoneWindow:
public class PhoneWindow extends Window implements MenuBuilder.Callback {
...
// This is the top-level view of the window, containing the window decor.
// 这是在窗口当中的顶层View,包含窗口的decor
private DecorView mDecor;
// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
// 这是窗口内容放置的视图,它要么是mDecor本身,要么是mDecor的子类的内容
ViewGroup mContentParent;
...
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
// 注释1
installDecor();
}
...
// 注释2
mLayoutInflater.inflate(layoutResID, mContentParent);
...
}
}
注释1处installDecor方法顾名思义就是初始化操作,注释2处就是将布局资源ID填充到mContentParent内容布局容器。先进入installDecor方法:
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
// 注释1
mDecor = generateDecor(-1);
...
}
if (mContentParent == null) {
// 注释2
mContentParent = generateLayout(mDecor);
...
}
}
注释1处,如果mDecor为空,就调用generateDecor方法,进入该方法就发现通过返回一个new出来DecorView,然后赋值给mDecor。注释2处调用generateLayout方法,那么该方法是如何给mContentParent赋值的呢?
protected ViewGroup generateLayout(DecorView decor) {
...
// 注释1
// 根据系统主题的属性设置了许多了特性
if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) {
requestFeature(FEATURE_ACTION_BAR_OVERLAY);
}
if (a.getBoolean(R.styleable.Window_windowActionModeOverlay, false)) {
requestFeature(FEATURE_ACTION_MODE_OVERLAY);
}
if (a.getBoolean(R.styleable.Window_windowSwipeToDismiss, false)) {
requestFeature