干就完事了 setContentView()探秘一
来源:互联网 发布:js bind()方法 编辑:程序博客网 时间:2024/04/27 21:42
1、源头 Activity的setContentView()
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
public Window getWindow() {
return mWindow;
}
mWindow其实就是一个PhoneWindow在Activity的attach方法里面 Policy.makeNewWindow
2、PhoneWindow
public void setContentView(int layoutResID) {installDecor();
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mLayoutInflater.inflate(layoutResID, mContentParent) ---Activity中setContentView(),其实主要就是mContentParent.addView(view),mContentParent是ViewGroup
3、ViewGroup
public void addView(View child, int index, LayoutParams params) {
requestLayout();//重点关注啊
invalidate(true);
addViewInner(child, index, params, false);
}
4、View的requestLayout()
public void requestLayout() {mParent.requestLayout();
}
重点是mParent.requestLayout(),调用会向上递归回到PhoneWindow里的mContentParent
mContentParent = generateLayout(mDecor);
protected ViewGroup generateLayout(DecorView decor) {
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
return contentParent ;
}
继续追下去findViewById()
public View findViewById(@IdRes int id) {
return getDecorView().findViewById(id);
}
哇原来如此啊 mContentParent的parent就是我们常在Activity里写的getWindow().getDecorView()
再看decor的parent是什么,Activity里面
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
public WindowManager getWindowManager() {
return mWindowManager;
}
//....
mWindowManager = mWindow.getWindowManager();
//....
追下去wm.addView(),Window类里面
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
public WindowManager getWindowManager() {
return mWindowManager;
}
追下去 WindowManagerImpl
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
mGlobal就是WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
//...
ViewRootImpl root;
//...
root = new ViewRootImpl(view.getContext(), display);
//...
root.setView(view, wparams, panelParentView);
//...
}
追下去root.setView(),ViewRootImpl类里面
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
//...
view.assignParent(this);
//...
}
assignParent()设置View的mParent,得知DecorView的parent就是ViewRootImpl
5、ViewRootImpl
requestLayout(){
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL,mTraversalRunnable, null);
}
mTraversalRunnable.run(){
doTraversal(){
performTraversals(){
performMeasure();
performLayout();
performDraw();
}
}
}
基本逻辑:
ViewGroup.addView(view)会调用requestLayout()
View.requestLyaout()每次都会递归回到Activity最上层的那个DecorView的parent就是ViewRootImpl
然后ViewRootImpl开始执行measure()、layout()、draw(),这几个方法里面会再递归遍历执行child View的measure()、layout()、draw()
- 干就完事了 setContentView()探秘一
- setContentView究竟干了什么?(API21)
- 研考完事了
- setContentView()探秘二
- 召回、退款就完事了? Note 7 的后续处理还得让三星焦头烂额
- java,不知不觉就干了这个。
- ionic发布App前的工作,别以为build一下就完事了(Publishing your app)
- 李彦宏:认准了就干下去,既不跟风,也不动摇
- 数据库update时这样干,你就悲剧了
- 程序员真的干到35就干不动了吗?
- 简历写好就完事了?这些事情你做了吗!
- 一晃眼,就老了
- 看看这个笑话,你就知道干IT的不容易了!!
- 看看这个笑话,你就知道干IT的不容易了!!
- 是创业失败还是根本就没有开始?这一年我都干了什么?
- setContentView到底做了什么
- SetContentView都做了什么
- 今天上午停电了,下午也停了1个多小时。所以没有干太多事情,就看来下书、
- cas 4.0 返回更多信息
- 排序遍历带前缀的文件名
- 100ITJAVA面试必考题系列(一)
- Android 6.0 动态权限申请
- 《机器学习实战》第三章 3.1 决策树的构造
- 干就完事了 setContentView()探秘一
- C# Word 文档保护
- HDU 1166 敌兵布阵 (线段树基础&树状数组基础)
- python与自然语言处理1 正则匹配
- 【第九周】646. Maximum Length of Pair Chain
- EM算法的九层境界:Hinton和Jordan理解的EM算法
- tablespace
- react+redux的升级版todoList
- 添加普通用户到 sudo 组