记录LayoutInflater三个参数方法的测试过程

本文详细解析了LayoutInflater的工作原理,探讨了不同参数组合下视图的加载行为,并对比了ListView与RecyclerView中视图加载的区别。

相信以下这行代码大家都不会陌生,在ListView的getView()和RecyclerView的onCreateViewHolder()中出现频率100%的一句代码:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
复制代码

第一个参数是资源布局文件,这个是自然不能少的,同时也可以忽略不再分析的参数,还剩下2个参数,root(根布局)和attachToRoot,root可以为null也可以不为null,attachToRoot可以为false也可以为true,这样就有4种组合了。

  1. !null,true;
  2. !null,false;
  3. null,true;
  4. null,false.

开始前先把资源布局文件准备好:

  1. 先来看看将要被添加到根布局中的child_layout布局文件:

     <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="200dp"
         android:background="#FF00FF">
     
         <Button
             android:layout_width="wrap_content"
             android:layout_height="100dp"
             android:text="button"/>
     </LinearLayout>
    复制代码
  2. 再看根布局文件,在这里就是Activity的布局:

     <?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:id="@+id/parent"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="#00F"
         android:orientation="vertical"
         tools:context="com.wjl.www.inflate.MainActivity">
     
     </LinearLayout>
    复制代码

上面已经准备好了,开始开车了:

  1. 根布局!=null,attachToRoot为true时的情况:

    1.1 的情况:

      LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
      View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, parentView, true);
    复制代码

    1.2 比1.1例子多一行代码,看会出现什么情况?

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, parentView, true);
     parentView.addView(childView);
    复制代码

    直接崩溃了:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.原因很简单,就是第三个参数是true且根布局不为null时已经添加到根布局了,现在addView()是重复添加了。

  2. 根布局!=null,attachToRoot为false时的情况:

    2.1 的情况

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, parentView, false);
    复制代码

    子View没有被添加进来,其实也可以理解,虽然上面的代码提供给inflate()方法提供了根布局,但是却不让子View去依附根布局,所以就不添加到根布局中了。

    2.2 比1.1例子多一行代码,看会出现什么情况?

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, parentView, false);
     parentView.addView(childView);
    复制代码

    效果和1.1的情况一模一样,不再上图了。

  3. 根布局==null,attachToRoot为true时的情况,预测一下结果,和2.1情况一样,还是要验证一下:

    3.1 情况

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, null, true);
    复制代码

    果真和2.1情况一样。

    3.2 会怎么样呢?

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, null, true);
     parentView.addView(childView);
    复制代码

    结论是:被加载进根布局了,但是还不太一样的就是child_layout中LinearLayout的高度设置失效了,但是Button的却没有失效。

  4. 根布局==null,attachToRoot为false时的情况:

    4.1 情况

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, null, false);
    复制代码

    其实结论都可以预测了,什么都没有被添加到根布局。

    4.再看看

     LinearLayout parentView = (LinearLayout) findViewById(R.id.parent);
     View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, null, false);
     parentView.addView(childView);
    复制代码

    效果和3.2一样。

综上所述可以得出结论:

PS:为什么不指定根布局子View的宽、高属性会失效呢?因为宽和高代表的意义是子View在一个容器中的大小,View自身+容器共同决定其大小,如果想让其属性生效,又不想给它一个容器,这时候就派上用场了(ListView适配器getView()或者RecyclerView的onCreateViewHolder()方法中一不小心写错,尺寸就不生效了)。

尺寸生效示例:
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv_pcr, parent, false);
尺寸失效实例:
 View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv_pcr, null, false);复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值