当前位置:网站首页>Drawing mechanism of view (I)
Drawing mechanism of view (I)
2022-07-02 07:26:00 【android_ Mr_ summer】
brief introduction
We are learning android When , Directly in xml It is specified in android The label of , Can show a variety of interfaces , But we don't know the drawing process , So as to hold a learning attitude , From the perspective of source code view The drawing mechanism of .
Catalog
1.view Drawing process of ( One )
2. summary
view Drawing process of
Before the analysis , We can take a look at the following flow chart first :
Every Activity All owned Window The object of ,Android by Window Provides a unique implementation class PhoneWindow.PhoneWindow After all Window, It doesn't have much View Related capabilities , however PhoneWindow Hold one of Android It's a very important part of View object Decor( decorate )View, It's in PhoneWindow The definitions in are as follows :
public class PhoneWindow extends Window{
// Top of the line view The node of , Play a window Decorated root component
private DecorView mDecor;
}
see DecorView The inheritance relationship tells us that ,DecorView Inherited from FrameLayout.
public class DecorView extends FrameLayout {
}
among DecorView The son of view It's a LinerLayout The layout contains TitleView and ContentView,ContentView The sub layout of is FrameLayout. We are usually in Activity Medium onCreate() In the method ,setContentView(int layoutResID) The incoming layout affects ContentView.
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
. . .
}
among getWindow() Namely PhoneWindow object , Among them setContentView() Method , Source code is as follows :
@Override
public void setContentView(int layoutResID) {
// mContentParent That is the above mentioned ContentView Parent container of , If NULL, call installDecor() Generate
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
// have FEATURE_CONTENT_TRANSITIONS The feature indicates that Transition
// mContentParent Not for null, The remove decorView All son View
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
// The general situation will come here , call mLayoutInflater.inflate() Method to fill the layout
mLayoutInflater.inflate(layoutResID, mContentParent);
}
. . .
// cb That is Window The associated Activity
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
// call onContentChanged() Callback method notification Activity The contents of the window have changed
cb.onContentChanged();
}
. . .
}
We mainly look at mLayoutInflater.inflate(layoutResID, mContentParent):
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
. . .
final XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
mConstructorArgs[0] = mContext;
View result = root;
try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
}
if (type != XmlPullParser.START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!");
}
final String name = parser.getName();
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("merge can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs);
} else {
View temp = createViewFromTag(name, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
temp.setLayoutParams(params);
}
}
rInflate(parser, temp, attrs);
if (root != null && attachToRoot) {
root.addView(temp, params);
}
if (root == null || !attachToRoot) {
result = temp;
}
}
} catch (XmlPullParserException e) {
InflateException ex = new InflateException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
InflateException ex = new InflateException(
parser.getPositionDescription()
+ ": " + e.getMessage());
ex.initCause(e);
throw ex;
}
return result;
}
}
From here we can clearly see ,LayoutInflater It's really just using Android Provided pull Parsing method to parse the layout file . We can notice that createViewFromTag() This method , Pass in the node name and parameters . See the method name , We should be able to guess , It is used to create... Based on the node name View Object's . stay createViewFromTag() The inside of the method will call createView() Method , Then use reflection to create View And return .
So let's do that view The root node of is created. Next, let's continue to check rInflate(parser, temp, attrs):
private void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs)
throws XmlPullParserException, IOException {
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String name = parser.getName();
if (TAG_REQUEST_FOCUS.equals(name)) {
parseRequestFocus(parser, parent);
} else if (TAG_INCLUDE.equals(name)) {
if (parser.getDepth() == 0) {
throw new InflateException("<include /> cannot be the root element");
}
parseInclude(parser, parent, attrs);
} else if (TAG_MERGE.equals(name)) {
throw new InflateException("<merge /> must be the root element");
} else {
final View view = createViewFromTag(name, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
rInflate(parser, view, attrs);
viewGroup.addView(view, params);
}
}
parent.onFinishInflate();
}
summary
You can see , The same is createViewFromTag() Method to create View Example , Then recursively call rInflate() Method to find this View Child elements below , After each recursion, this View Add to parent layout . In this way, after the entire layout file is parsed, a complete DOM structure , Finally, the top-level root layout will be returned to , thus inflate() It's all over .
Let's keep on learning view The drawing mechanism of ( Two )
边栏推荐
- Network security -- intrusion detection of emergency response
- Oracle EBS DataGuard setup
- [introduction to information retrieval] Chapter 7 scoring calculation in search system
- Explain in detail the process of realizing Chinese text classification by CNN
- Explanation of suffix of Oracle EBS standard table
- Oracle EBs and apex integrated login and principle analysis
- 中年人的认知科普
- Delete the contents under the specified folder in PHP
- sparksql数据倾斜那些事儿
- Take you to master the formatter of visual studio code
猜你喜欢
Practice and thinking of offline data warehouse and Bi development
Check log4j problems using stain analysis
[tricks] whiteningbert: an easy unsupervised sentence embedding approach
【信息检索导论】第六章 词项权重及向量空间模型
Take you to master the formatter of visual studio code
ssm超市订单管理系统
第一个快应用(quickapp)demo
SSM二手交易网站
中年人的认知科普
SSM实验室设备管理
随机推荐
使用MAME32K进行联机游戏
SSM supermarket order management system
SSM二手交易网站
pySpark构建临时表报错
sparksql数据倾斜那些事儿
ORACLE 11G利用 ORDS+pljson来实现json_table 效果
ERNIE1.0 与 ERNIE2.0 论文解读
Spark SQL task performance optimization (basic)
ssm+mysql实现进销存系统
Principle analysis of spark
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory'
离线数仓和bi开发的实践和思考
SSM personnel management system
Explanation of suffix of Oracle EBS standard table
Only the background of famous universities and factories can programmers have a way out? Netizen: two, big factory background is OK
聊天中文语料库对比(附上各资源链接)
Classloader and parental delegation mechanism
Illustration of etcd access in kubernetes
DNS attack details
Oracle EBS database monitoring -zabbix+zabbix-agent2+orabbix