A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

inflater.inflate(R.layout.resource, root,false);
我们在添加布局的时候经常会用到inflate方法,但其中三个参数应该怎么使用?有什么作用大家清楚吗?
resource      你要添加的布局文件
root        添加到哪一个布局
AttachToRoot    是否添加的布局中(true添加,false不添加)。
参数是这样解释,就结束了吗?
下面来看看root、AttachToRoot参数对应改变的时候,对应的效果。

1.当root为null时,AttachToRoot为true的时候。

表示将resource指定的布局添加到root中,添加的过程中resource所指定的的布局的根节点的各个属性都是有效的。

root 根布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/ll"
    tools:context="org.sang.layoutinflater.MainActivity">
</LinearLayout>



添加的布局R.layout.linearlayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@color/colorPrimary"
    android:gravity="center"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        LayoutInflater inflater = LayoutInflater.from(this);
        inflater.inflate(R.layout.linearlayout, ll,true);
    }

这样就把R.layout.linearlayout添加到ll这个布局中,效果图如下:把R.layout.linearlayout中的属性,都添加了进来。



但如果手残,在下面多加一行代码。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.linearlayout, ll, true);
        ll.addView(view);
    }

这样就会包错了,提示:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

原因就是当AttachToRoot为true的时候,已经把resource添加到了root中了,再次添加就会报子孩子已经有爹了,不能在认一个爹。

2.当root不为null,AttachToRoot为false时。

都不添加到布局中去了,为什么root不设置为null,设置root还有什么意义呢?这里涉及到另外一个问题:我们在开发的过程中给控件所指定的layout_width和layout_height到底是什么意思?
该属性的表示一个控件在容器中的大小,就是说这个控件必须在容器中,这个属性才有意义,否则无意义。这就意味着如果我直接将linearlayout加载进来而不给它指定一个父布局,
则inflate布局的根节点的layout_width和layout_height属性将会失效(因为这个时候linearlayout将不处于任何容器中,那么它的根节点的宽高自然会失效)。如果我想让linearlayout的根节点有效,
又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。这样,指定root的目的也就很明确了,即root会协助linearlayout的根节点生成布局参数,只有这一个作用。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.linearlayout, ll, false);
        ll.addView(view);
    }

如果attachtoroot为false,我们想让布局添加到root中,就需要在最后手残一下子了,把view添加到root中去。效果和上图一样。

3.root为null,AttachToRoot为false和true都一样,因为当root为null的时候,第三个参数没有意义。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.linearlayout, null, false);
        ll.addView(view);
    }

同样是上文中的添加view代码。效果如下:   为什么会这要,因为在前面提到过,root会帮助view创建parmas参数。如果没有root,parmas就没法创建,相当于没有设置宽、高属性。这个时候去设置button的属性,就ok了。



大家可以看下源码,还是比较容易懂得。

google是通过pull解析,来解析xml文件,下面是摘取的源码。  如果root!= null ,生成params,  如果root不为null、AttachToRoot为true, addview(temp,params),如果root为null,直接返回view。

final View temp = createViewFromTag(root, name, inflaterContext, attrs);

        ViewGroup.LayoutParams params = null;

        if (root != null) {
          params = root.generateLayoutParams(attrs);
          if (!attachToRoot) {
            temp.setLayoutParams(params);
          }
        }

        rInflateChildren(parser, temp, attrs, true);


        if (root != null && attachToRoot) {
          root.addView(temp, params);
        }

        if (root == null || !attachToRoot) {
          result = temp;
        }
  return result;

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马