当前位置:网站首页>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 )
边栏推荐
- ORACLE APEX 21.2安裝及一鍵部署
- 使用 Compose 实现可见 ScrollBar
- 【信息检索导论】第一章 布尔检索
- Two table Association of pyspark in idea2020 (field names are the same)
- MySQL组合索引加不加ID
- Three principles of architecture design
- Module not found: Error: Can't resolve './$$_ gendir/app/app. module. ngfactory'
- 华为机试题
- 外币记账及重估总账余额表变化(下)
- 软件开发模式之敏捷开发(scrum)
猜你喜欢

Oracle 11g uses ords+pljson to implement JSON_ Table effect

【模型蒸馏】TinyBERT: Distilling BERT for Natural Language Understanding

Implementation of purchase, sales and inventory system with ssm+mysql

【信息检索导论】第三章 容错式检索

ORACLE EBS 和 APEX 集成登录及原理分析

Check log4j problems using stain analysis

離線數倉和bi開發的實踐和思考

Cognitive science popularization of middle-aged people

CSRF attack

SSM二手交易网站
随机推荐
Spark SQL task performance optimization (basic)
parser. parse_ Args boolean type resolves false to true
ARP attack
ssm+mysql实现进销存系统
One field in thinkphp5 corresponds to multiple fuzzy queries
Explain in detail the process of realizing Chinese text classification by CNN
Using MATLAB to realize: power method, inverse power method (origin displacement)
Typeerror in allenlp: object of type tensor is not JSON serializable error
[introduction to information retrieval] Chapter 7 scoring calculation in search system
[Bert, gpt+kg research] collection of papers on the integration of Pretrain model with knowledge
ORACLE EBS接口开发-json格式数据快捷生成
Cognitive science popularization of middle-aged people
sparksql数据倾斜那些事儿
Implementation of purchase, sales and inventory system with ssm+mysql
Oracle EBs and apex integrated login and principle analysis
[introduction to information retrieval] Chapter 3 fault tolerant retrieval
【信息检索导论】第六章 词项权重及向量空间模型
pySpark构建临时表报错
RMAN incremental recovery example (1) - without unbacked archive logs
Interpretation of ernie1.0 and ernie2.0 papers