博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android View 源码解析(二) - LayoutInflater
阅读量:5823 次
发布时间:2019-06-18

本文共 7851 字,大约阅读时间需要 26 分钟。

继之后接着说

之前我们分析了setContentView方法的相关代码 接下来说说LayoutInflater的方法

LayoutInflater源码分析

  1. 与setContentView相关

在PhoneWindow的generateLayout中调用了

View in = mLayoutInflater.inflate(layoutResource, null);复制代码
  1. LayoutInflater中获取实例化方法
/**   * Obtains the LayoutInflater from the given context.   */  public static LayoutInflater from(Context context) {      LayoutInflater LayoutInflater =              (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);      if (LayoutInflater == null) {          throw new AssertionError("LayoutInflater not found.");      }      return LayoutInflater;  }复制代码
  1. inflate方法相关
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {      return inflate(resource, root, root != null);  }  public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {    return inflate(parser, root, root != null);  }复制代码
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {      final Resources res = getContext().getResources();      if (DEBUG) {          Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("                  + Integer.toHexString(resource) + ")");      }      final XmlResourceParser parser = res.getLayout(resource);      try {          return inflate(parser, root, attachToRoot);      } finally {          parser.close();      }  }复制代码

最后发现都需要调用

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {        synchronized (mConstructorArgs) {            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");            final Context inflaterContext = mContext;            final AttributeSet attrs = Xml.asAttributeSet(parser);            Context lastContext = (Context) mConstructorArgs[0];            mConstructorArgs[0] = inflaterContext;            //定义返回值 初始化传入形参 root            View result = root;            try {                // 找到根节点                int type;                while ((type = parser.next()) != XmlPullParser.START_TAG &&                        type != XmlPullParser.END_DOCUMENT) {                }                //验证type是否为Start_Tag  保证xml文件正确                if (type != XmlPullParser.START_TAG) {                    throw new InflateException(parser.getPositionDescription()                            + ": No start tag found!");                }                //type为 root node                final String name = parser.getName();                if (DEBUG) {                    System.out.println("**************************");                    System.out.println("Creating root view: "                            + name);                    System.out.println("**************************");                }                if (TAG_MERGE.equals(name)) {                    //处理 merge相关                    //root需要非空 且attachToRoot为空                    if (root == null || !attachToRoot) {                        throw new InflateException("
can be used only with a valid " + "ViewGroup root and attachToRoot=true"); } //递归inflate 方法调用 rInflate(parser, root, inflaterContext, attrs, false); } else { //根据tag节点创建view对象 final View temp = createViewFromTag(root, name, inflaterContext, attrs); ViewGroup.LayoutParams params = null; if (root != null) { if (DEBUG) { System.out.println("Creating params from root: " + root); } //根据root生成LayoutParams params = root.generateLayoutParams(attrs); if (!attachToRoot) { //如果attachToRoot为flase 则调用setLayoutParams temp.setLayoutParams(params); } } if (DEBUG) { System.out.println("-----> start inflating children"); } //递归inflate剩下的children rInflateChildren(parser, temp, attrs, true); if (DEBUG) { System.out.println("-----> done inflating children"); } // We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { //root非空且attachToRoot=true则将xml文件的root view加到形参提供的root里 root.addView(temp, params); } // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) { //返回xml里解析的root view result = temp; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (Exception e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; } Trace.traceEnd(Trace.TRACE_TAG_VIEW); //返回参数root或xml文件里的root view return result; } }复制代码

相关inflate参数的结果

  1. 相关方法解析 在Inflate中多次被调用的rInflate
void rInflate(XmlPullParser parser, View parent, Context context,           AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {       final int depth = parser.getDepth();       int type;       //XmlPullParser解析器的标准解析模式       while (((type = parser.next()) != XmlPullParser.END_TAG ||               parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {           //找到start_tag节点           if (type != XmlPullParser.START_TAG) {               continue;           }           //获取Name标记           final String name = parser.getName();           //private static final String TAG_REQUEST_FOCUS = "requestFocus";           //处理requestFocus           if (TAG_REQUEST_FOCUS.equals(name)) {               parseRequestFocus(parser, parent);           // private static final String TAG_TAG = "tag";           //处理tag           } else if (TAG_TAG.equals(name)) {               parseViewTag(parser, parent, attrs);           //private static final String TAG_INCLUDE = "include";           //处理include           } else if (TAG_INCLUDE.equals(name)) {               //如果是根节点则抛出异常               if (parser.getDepth() == 0) {                   throw new InflateException("
cannot be the root element"); } parseInclude(parser, context, parent, attrs); //private static final String TAG_MERGE = "merge"; //处理merge merge需要是xml中的根节点 } else if (TAG_MERGE.equals(name)) { throw new InflateException("
must be the root element"); } else { final View view = createViewFromTag(parent, name, context, attrs); final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflateChildren(parser, view, attrs, true); viewGroup.addView(view, params); } } //parent的所有子节点都处理完毕的时候回onFinishInflate方法 if (finishInflate) { parent.onFinishInflate(); } } //可以添加自定义逻辑 protected void onFinishInflate() { }复制代码

转载地址:http://hqbdx.baihongyu.com/

你可能感兴趣的文章
MySQL案列之主从复制出错问题以及pt-slave-restart工具的使用
查看>>
linux 查看剩余内存数
查看>>
测试人员容易遗漏的隐藏缺陷
查看>>
JS方法:数字转换为千分位字符
查看>>
maven+SpringMVC搭建RESTful后端服务框架
查看>>
[BalkanOI2016]Cruise
查看>>
一本书的摘录
查看>>
重排序(转载)
查看>>
python+selenium之字符串切割操作
查看>>
串结构练习——字符串匹配
查看>>
linux下输入密码不回显
查看>>
《构建之法》读书笔记
查看>>
拿下阿里、头条、滴滴的offer后谈谈面试经验---动身前看一看
查看>>
android开发(49) android 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏
查看>>
【ERP】如何在多行数据块中实现仅能勾选唯一的主联系人
查看>>
Oracle 数据库优化的R方法(Method R)
查看>>
CentOS最小化安装系统开启网卡
查看>>
互联网+升级到智能+ 开启万物智联新时代
查看>>
Nginx + Tomcat (java )服务器部署
查看>>
Linux文本编辑器之Nano
查看>>