LayoutInflater那些事儿

对于android初学者而言,看到LayoutInflater只能说是“爱过“。在自定义控件的时候构造函数中会LayoutInflater.from(mContext).inflater(layout_id, this);还有重写
适配器布局会LayoutInflater.from(getContext()).inflater(layout_id, null);当时我也是只知道这样用,具体怎么回事不是太清楚,今天就事论事,聊一聊LayoutInflater那些事儿。


首先我们要知道获取LayoutInflater实例有三种方式,并且本质都是一样的:

  1. LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
  2. LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  3. LayoutInflater inflater = LayoutInflater.from(context);

读过源码的就会知道,三种最后都会执行到mContext.getSystemService()。

额,再来说说inflater方法,这个方法重载过一次,有两种形式:

  1. inflater(int resource, ViewGroup root);
  2. inflater(int resource, ViewGroup root, boolean attachToRoot);

然而第一种方法本质是inflater(int resource, ViewGroup root, root != null);所以这两个也是有联系的。

实践出真理,写个小demo,新建两个布局文件:
activity_main.xml:

<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="200dp"
    android:background="#555"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="测试"
        android:textColor="#abc"
        android:textSize="40sp" />

</LinearLayout>

test.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="250dp"
    android:layout_height="match_parent"
    android:background="#478"
    android:orientation="vertical">

</LinearLayout>

非常简单的两个布局,然后我们在MainActivity中编写:

View test = getLayoutInflater().inflate(R.layout.test, null);
setContentView(test);

运行程序:

这里写图片描述

发现宽和高并不是我们自己定义的250dp,是不是巧合咧,改下代码:

View main = getLayoutInflater().inflate(R.layout.activity_main, null);
setContentView(main);

这里写图片描述

呀哈,这就奇了怪了,为什么有这种情况,不要急,细细道来。

网上看源码分析的demo一搜几个G,我就不扯了,inflater(int resource, ViewGroup root, boolean attachToRoot)三个参数的意义:

  1. resource:不说也知道,布局的id
  2. root:该视图的根布局
  3. attachToRoot:是否将该视图添加到根布局中并返回

inflater的视图宽高,只有匹配到root根布局才会正常计算,不信你去看源码,反正我是信了。
只看解释可能没有什么说服力,那我们再修改代码:

View main = getLayoutInflater().inflate(R.layout.activity_main, null);
View test = getLayoutInflater().inflate(R.layout.test, (ViewGroup) main);
setContentView(test);

这里写图片描述

首先inflater一个main布局,因为root传的null所以宽高并不是我们自己定义的宽高,然后inflater一个test布局,这个布局传的root是main布局,后面的attachToRoot我没写出来,大家都应该知道是true吧,所以会正确的加载test布局,并把test布局添加到main布局中并返回。

有疑问,没关系,我们将

View test = getLayoutInflater().inflate(R.layout.test, (ViewGroup) main);

改成

View test = getLayoutInflater().inflate(R.layout.test, (ViewGroup) main, false);

按照上面的说法这里还是会正确加载test布局,但并不会将test添加到main布局中,我们再运行看看:
这里写图片描述

的确是这样,证明了我们上述的猜测是对的。

好了,如果你一行一行地看到了这里,相信你也明白了十之八九,好了,不知道大家有没有遇到一个问题,在自定义adapter中listview不能正常显示item的宽高,当初为了这个抓破头皮屑。。最简单的解决方法就是在不要穿root为空值,记得后面的参数传false哦。

可能见解看法有偏差,虚心接受大牛们的评教。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值