一篇弄懂LayoutInflater.from(context).inflate()

昨天项目的原因,使用到了这个LayoutInflater.from(context).inflate(),结果发现应该加载的布局没有显示出来。排查了好久发现是照着别人view的时候,直接把LayoutInflater.from(context).inflate(R.layout.item, null)照写了,然后就没加载出来。所以今天整理一下昨天出现的问题。

LayoutInflater.from(context).inflate()

这个方法有几个重载方法,其中主要使用的参数简单的解释一下。

1  int resource  代表需要加载资源的id

2 ViewGroup root 代表资源需要被添加的地方

3 boolean attachToRoot 是否要被添加到root中

4 XmlPullParser parser 代表xml文件

使用LayoutInflater.from(context).inflate()主要有两种方式,第一种是传入资源布局id,第二种是传入xml文件。分别如图所示

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}

public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
return inflate(parser, root, root != null);
}

可以看到实际上这两种方式调用的都是带有attachToRoot的三个参数的重载方法。

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
if (DEBUG) {
Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
+ Integer.toHexString(resource) + ")");
}

final XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}

通过源码我们可以看到实际上,通过资源id传入值,会将id转化成xml文件,所以其实底层都是将xml传入并进行绘制和加载。

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
…………
}

由于这个方法代码太长了就不展示出来了,主要就是将xml文件进行解析,然后分别绘制。

再回顾一下带有两个参数的方法,他们的attachToRoot都是root != null,也就是如果root==null,就不添加(null没地方可以添加view);如果root!=null,换句话说如果view被指定了添加到哪个viewgroup中,那么attachToRoot默认为true。这很好理解。

如果上述例子太抽象,就举个例子

首先我有一个activity,它的布局文件和java代码如下。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_containter"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

</LinearLayout>

package com.example.myapplication;

import android.view.LayoutInflater;
import android.widget.LinearLayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout mainContainer=findViewById(R.id.main_containter);
LayoutInflater.from(this).inflate(R.layout.my_view,null);

}
}

被添加的view 布局文件如下所示,很简单就是一个正方形的textview

<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="@+id/text"
android:layout_width="100dp"
android:layout_height="100dp"/>

运行效果如下所示

如果将代码改成

LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer);//相当于attachRoot=true

运行效果如下所示

可以发现,此时view被添加到了布局中并显示出来了。

再改一下,将attachRoot设置为false,可以猜想到view不会被添加到activity中。

LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,false);

运行结果也如同我们到猜想。

此时再改变一下,通过addView添加。

View view=LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,false);
mainContainer.addView(view);

运行效果如同LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,ture)

通过这里的实验可以做一个推测

View view=LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,false);
mainContainer.addView(view);

等于

View view=LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,true);

这也反过来验证了attachRoot的作用就是将view添加到viewgroup中,作用和addview类似。

还有最后一个问题

LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,false) 和LayoutInflater.from(this).inflate(R.layout.my_view,null)有什么区别呢?

这里我们要知道,当我们设置layout_width和layout_height时必须在一个容器中才有意义。也就是说当我们上面的textview的宽高为100dp的时候,必须指定root才有效果,否则会失效。

看下面的例子

view=LayoutInflater.from(this).inflate(R.layout.my_view,mainContainer,false);
mainContainer.addView(view);

为了直观方便展示我们将这个view显示出来,效果如图所示,一切正常。

当我们这样设置时,可以发现有了变化,对于textview的宽高设置没有设置生效。

view=LayoutInflater.from(this).inflate(R.layout.my_view,null);
    mainContainer.addView(view);

最后可以看到,当不指定root时,需要添加的view所设置的布局属性会失效。至此应该算是搞懂LayoutInflater.from(context).inflate()三个参数的作用,以及他们分别的使用情况了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个方法是在Android开发中使用的,可以通过LayoutInflater类的from方法获取到一个LayoutInflater实例,然后调用其inflate方法来加载布局文件,将其转化为一个View对象,以供使用。 ### 回答2: layoutinflater.from(context).inflate是Android中一个比较常见的方法,主要用于将布局文件转换成可在代码中使用的View对象。以下是详细的解释: 首先,LayoutInflater是一个Android系统类,其作用是将布局文件转换成可在代码中实现的View对象。而从context.getParameter()方法中返回一个LayoutInflater示例后,需要使用其inflate()方法来加载布局文件,返回一个View对象。inflate()方法有三个参数:布局文件ID、父View以及一个布尔标志。 在大多数情况下,第二个参数都为null,这意味着在加载布局文件时没有父元素。而第三个参数标志通常设置为false,这意味着在加载布局文件时不附加给指定父元素。 因此,调用LayoutInflater.from(context).inflate(R.layout.my_layout, null, false)会返回一个View对象,该对象表示my_layout.xml布局文件的内容。可以将此对象添加到任何视图层次结构中,例如: ViewGroup parent = findViewById(R.id.parent_layout); View child = LayoutInflater.from(context).inflate(R.layout.my_layout, parent, true); parent.addView(child); 在这种情况下,inflate()方法的第二个参数是父元素的引用,表示新加载的View对象将成为此父元素的一部分。第三个参数标志设置为true,这意味着从布局文件加载的视图将自动成为传递给inflate()方法的父元素的一部分。 总之,LayoutInflater.from(context).inflate是Android开发中非常有用的一个方法,它使您可以轻松地将布局文件转换为可在代码中操作的View对象。了解它的用法可以使您更轻松地开发高质量的Android应用程序。 ### 回答3: layoutinflater.from(context).inflate 是 Android 中一种常见的布局填充方法。在 Android 中,我们通常使用 XML 文件创建布局,然后使用 Java 代码调用该布局以填充视图。其中,layoutinflater.from(context) 是获取一个 LayoutInflater 对象的方法,它可以用于动态将布局文件转换为其对应的视图对象并在当前视图中添加。 在上述代码中,context 是用于创建视图的上下文对象,inflate 是用于执行布局填充的方法。该方法中需要传入一个布局文件ID,该 ID 用于确定要填充的布局文件的位置和名称。被填充的布局文件中包含了布局中的所有 View 对象及其属性,包括控件大小、边距、背景等等。填充完成后,该布局文件中的所有视图都将被转换为 Java 中的 View 类型,并作为整个填充视图的一部分添加到 ViewGroup 中。 通常情况下,我们会在 Activity 中调用该方法以填充视图对象,然后通过 findViewById 对填充好的视图对象中的控件进行定位,并对其进行任何必要的更改或操作。这样,我们就可以通过代码实现 UI 界面中各种复杂的布局效果,并实现超出 XML 文件所能实现的更高级的 UI 界面效果。 总之,layoutinflater.from(context).inflate 是 Android 中一种非常常见的布局填充方法,它允许我们将布局文件转换为对应的 View 对象,并添加到当前视图中。这种方法在 Android 应用程序开发中非常有用,特别是在创建 UI 界面时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值