对于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. Android(安卓)RecyclerView控件
  2. 个人经验 - Android的RelativeLayout布局的layout_height属性设
  3. Android换肤Demo
  4. 关于Android(安卓)7.0下Launcher3下default_workspace.xml修改无
  5. ScrollView中的控件占据ScrollView的match_parent
  6. Android(安卓)Material Design Library系列教程(三)
  7. android studio 工程在android 源码编译
  8. [置顶] Android(安卓)ListView 基础入门 简介以及深入优化
  9. Android9.0版本Vold服务源码分析之上层处理SD卡挂载

随机推荐

  1. android 获取屏幕高度,宽度,状态栏高度
  2. Android(安卓)之 Looper、MessageQueue、
  3. (译)Android(安卓)性能优化总览
  4. Android仿QQ主界面-------完善篇
  5. Android(安卓)ROM 开发技能图谱
  6. android 学习八 android selector的使用
  7. Android(安卓)TextView文字横向自动滚动(
  8. Android自己动手实现下拉刷新控件(1)----典
  9. React Native Android(安卓)ScrollView
  10. Android(安卓)网络安全配置