LayoutInflater.inflate详解

泡在网上的日子 / 文 发表于2015-01-07 13:48 次阅读 LayoutInflater

 LayoutInflater概述

从XML文件中实例化一个布局成对应的View类, 它从来不会直接使用, 而是使用getLayoutInflater()或者getSystemService(String)来获得一个对应当前context的标准LayoutInflater 实例。

例如:    

LayoutInflater inflater = (LayoutInflater)context.getSystemService

      (Context.LAYOUT_INFLATER_SERVICE);

 

如果要在自己的views中通过LayoutInflater.Factory来创建LayoutInflater你可以用cloneInContext(Context)来克隆一个当前存在的ViewFactory然后再用setFactory(LayoutInfalter.FActory) 来设置成自己的FActory.

起因

原来在项目中一直习惯用inflater.inflate(R.layout.layout, null)最近却发现会有一个黄色的警告。 十分好奇,所以决定找出原因。

我们发现inflate方法有两个:

  • View inflate(int resource, ViewGroup root)

  • View inflate(int resource , ViewGroup root, boolean attachToRoot) 第二个参数是指实例的布局所要放入的根视图。
    一般我们在不需要将该布局放入根视图的时候都会把第二个参数传为null,这样系统就不会去进行相应的绑定操作了,不然就蹦了。 我相信很多人都会这样理解,所以都很少用到 第二个方法, 其实这样是错误的。

原因在于android:layout_xyz属性会在父视图中重新计算,而你用第一个方法是说需要被添加到父视图中,只不过你不知道添加到哪一个父视图中, 所以你在xml中定义的LayoutParams 就会被忽略(因为没有已知的父视图)。

示例

大家肯定遇到过在ListViewitem布局中设置的高度没有效果的问题。

<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android
"

    android:layout_width="match_parent"

    android:layout_height="100dip"

    android:gravity="center_vertical"

    android:orientation="horizontal">

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="test" />

</LinearLayout>
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {

        convertView = inflate(R.layout.item_lv_test, null);

    }

    return convertView;

}

如果用上面的代码会发现设置100dp是无效的。

而如果换成下面的代码就可以了。

public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {

        convertView = inflate(R.layout.item_lv_test, null, false);

    }

    return convertView;

}

这里你该会想一想为什么很多需要显示View的方法中都有ViewGroup这个参数。
所以有些人会说在跟布局中设置是无效的,要再嵌套一层布局。 这样是错误的,会造成布局层级增多,影响性能。

 

细节

  • setContentView()LayoutInfalter.inflate()的区别 setContentView()一旦调用,就会立即显示UI. 而LayoutInfalter.inflate()只是把布局转换成对应的View对象,不会立即显示,只有需要的时候再显示出来。

  • View.inflate()方法与LayoutInflater.inflate()的区别 直接上源码:

public static View inflate(Context context, int resource, ViewGroup root) {

    LayoutInflater factory = LayoutInflater.from(context);

    return factory.inflate(resource, root);

}

 转自  CharonChui的Android笔记  纠正了几个错别字

收藏 赞 (13) 踩 (21)
上一篇:OkHttp使用教程
Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient。 关于HttpURLConnection和HttpClient的选择官方博客 尽管Google在大部分安卓版本中推荐使用HttpURLConnection,但是这个类相比HttpClient实在是太难用,太弱爆了。 OkHttp是一个相对成熟的
下一篇:Android源码下载和编译总结
前几天常用的笔记本电脑挂了,要拿去维修,于是就准备用另一台备用电脑来重新下载和编译一下Android源码,以便工作研究之用。鉴于 最近一直都有人问下载和编译Android源码的问题,并且我上一次写Android源码编译的文章已经是2011年的事情,于是就趁这个机会