Android LayoutInflater.inflate使用上的问题解惑

最近在在使用LayoutInflater.inflate方法时遇到了一些问题,以前没有仔细看过此类的使用方法,故将其记录下来,方便日后查阅。

相信大家都知道LayoutInflater.inflate是在android开发遇到的一些使用频率是非常高的方法,如果使用不好的,就会出现一些奇怪的问题。

一个例子如下:

1,一个主布局文件如下

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">

    <ListView        android:id="@+id/list_view"        android:layout_width="match_parent"        android:layout_height="wrap_content">

    </ListView>

</RelativeLayout>

上述的布局文件非常简单,只是在Relative文件中添加了一个ListView.

2,ListView的子View item的布局文件如下
<?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="100dp"    android:orientation="vertical"    android:background="@android:color/holo_red_dark">

    <TextView        android:id="@+id/list_item"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:gravity="center"        android:textSize="20dp"        android:textColor="@android:color/black"/></LinearLayout>
生成的预览图如下:

为了明显起见,此处将背景设为红色。

3,设置ListView的adapter,adapter的getView方法如下:public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null){        convertView = mInflater.inflate(R.layout.list_item,null);    }

    TextView textView = (TextView)convertView.findViewById(R.id.list_item);    textView.setText(position + "");    return convertView;}

最终的样式如下:
可以从测试结果中明显的看出,list_item.xml中设置的高度没有生效,很有可能是ListView的adapter中getView方法中
mInflater.inflate(R.layout.list_item,null),这里的问题。

于是改成 mInflater.inflate(R.layout.list_item,parent,false),再次运行结果如下:

上述正是我们想要的结果,下面就针对上述问题结合源码分析下LayoutInflater.inflate方法的使用.

可能有不少的人都不知道LayoutInflater.inflate还有第三个参数,此方法的参数如下:
public View inflate(int resource, ViewGroup root, boolean attachToRoot).

从源码可以得知,不管是 public View inflate(int resource, ViewGroup root)还是
public View inflate(int resource, ViewGroup root, boolean attachToRoot),最终都是调用了
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)。

上述我们例子中调用了
public View inflate(int resource, ViewGroup root),让我们看下此方法的代码如下:public View inflate(int resource, ViewGroup root) {
    return inflate(resource, root, root != null);}

public View inflate(int resource, ViewGroup root, boolean attachToRoot) {    if (DEBUG) System.out.println("INFLATING from resource: " + resource);    XmlResourceParser parser = getContext().getResources().getLayout(resource);    try {        return inflate(parser, root, attachToRoot);    } finally {        parser.close();    }}

可以发现不管是 public View inflate(int resource, ViewGroup root)还是
public View inflate(int resource, ViewGroup root, boolean attachToRoot),最终都是调用了
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)。

上述例子中调用inflate(R.layout.list_item,null),从上述源码中可以看出最终传给
inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)方法的参数转变为

inflate(XmlPullParser parser,null,false);

下面重点针对
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)方法进行分析,下面只列出了其核心部分的代码在471行可以看到,当root ! = null时,通过root产生子 view的LayoutParams,此时如果attachToRoot为true,则将此子View 添加进root view,并返回root view;

如果attachToRoot为false则直接返回parser解析的view;

如果root == null,此时直接返回parser解析出来的view,并未设置此view的LayoutParams,此view的LayoutParams将会在被添加时由Parent View赋予值,这就是上述例子第一次的写法没有生效的原因。

针对以上的分析,归纳如下:
  1. 调用LayoutInflater.inflate方法,并且将root参数设置为null,就等于忽略了xml布局文件中的layout_×参数
  2. 如果root不为null,并且attachRoot=true,那么就会根据root生成一个布局文件ViewLayoutParam对象,并且将这个View添加到root中去,并且返回这个rootView
  3. 因此,最好还是使用这个代码吧:View v1 = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, false);
				
时间: 2024-10-05 16:26:41

Android LayoutInflater.inflate使用上的问题解惑的相关文章

Android LayoutInflater.inflate的使用及源码分析

欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/61913656 本文出自:[余志强的博客] 在实际开发中我们常常需要inflate要给布局然后添加到某个布局容器里面去, 要把xml布局文件转成一个View对象 需要使用LayoutInflater.inflate方法. 在开发中常常使用如下几种方式: inflater.inflate(layoutId, null); inflater.inflate(layoutI

android LayoutInflater.inflate详解

LayoutInflater概述 从XML文件中实例化一个布局成对应的View类, 它从来不会直接使用, 而是使用getLayoutInflater()或者getSystemService(String)来获得一个对应当前context的标准LayoutInflater 实例. 例如: 1 2 3 LayoutInflater inflater = (LayoutInflater)context.getSystemService       (Context.LAYOUT_INFLATER_SE

android LayoutInflater.inflate()的参数介绍

LayoutInflater.inflate()的作用就是将一个xml定义的布局文件实例化为view控件对象: 与findViewById区别: LayoutInflater.inflate是加载一个布局文件: findViewById则是从布局文件中查找一个控件: 一.获取LayoutInflater对象有三种方法 LayoutInflater inflater=LayoutInflater.from(context); LayoutInflater inflater=getLayoutInf

Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解

方法inflate(int resource, ViewGroup root, boolean attachToRoot) 中 第一个参数传入布局的资源ID,生成fragment视图,第二个参数是视图的父视图,通常我们需要父视图来正确配置组件.第三个参数告知布局生成器是否将生成的视图添加给父视图. 我们新建一个项目测试一下: activity_main.xml <?xml version="1.0" encoding="utf-8"?> <Line

Android LayoutInflater.inflate()的参数及其用法

很多人在网上问LayoutInflater类的用法,以及inflate()方法参数的含义,现解释如下: inflate()的作用就是将一个用xml定义的布局文件查找出来,注意与findViewById()的区别,inflate是加载一个布局文件,而findViewById则是从布局文件中查找一个控件. 1.获取LayoutInflater对象有三种方法 LayoutInflater inflater=LayoutInflater.from(this); LayoutInflater inflat

[Android]LayoutInflater的inflate方法半详解

好久没写博客,作为一名刚加入android阵营的android狗,发心得刷人气来了!!!(半详解是因为说详不那么详,说不详也稍微有点详..)哈哈~~..咳..咳.. 一.Activity中的setContentView 对于刚开始学Android的新手来说,在Activity中加载布局文件的方法是在onCreate()回调方法中直接调用setContentView()方法,如: @Override protected void onCreate(Bundle savedInstanceState

Android LayoutInflater.from().inflate()源码解析

我们知道,在Activity#setContentView()中会调用PhoneWindow#setContentView().而在PhoneWindow#setContentView()中有这么一句mLayoutInflater.inflate(layoutResID, mContentParent).这行代码的作用是将我们的activity_main.xml填充到mContentParent中去.详见:setContentView源码解析.在写adapter的时候,也经常写mInflater

Android - LayoutInflater和inflate方法的用法

在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化:而findViewById()是找xml布局文件下的具体widget控件(如 Button.TextView等). 具体作用: 1.对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入: 2.对于一个已经载入的界面,就可以使用Activiyt

【android】LayoutInflater.inflate方法的详解及xml根元素的布局参数不起作用的问题

一.首先看带三个参数的inflate方法: public View inflate (int resource, ViewGroup root, boolean attachToRoot) 1.如果root不为null,且attachToRoot为TRUE,则会在加载的布局文件的最外层再嵌套一层root布局,这时候xml根元素的布局参数当然会起作用. 2.如果root不为null,且attachToRoot为false,则不会在加载的布局文件的最外层再嵌套一层root布局,这个root只会用于为