通过上面的翻译,我想对LayoutInflater的简单理解如下:
LayoutInflater 是一个视图填充器;获取LayoutInflater,需要通过Activity.getLayoutInflater()或者Context.getSystemService();可以自定义一个新的LayoutInflater(我还没遇到过,不太理解); LayoutInflater 仅适用于构建的XML 布局编译的R 文件返回的XmlPullParse 有效;
二、LayoutInflater的获取
第一种方法:从给定的上下文中获取LayoutInflater:
LayoutInflater inflater=LayoutInflater.from(context);第二种方式:在Activity中获取LayoutInflater:
LayoutInflater 充气器=getLayoutInflater();第三种方式:通过context.getSystemService()获取:
LayoutInflater inflater=context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);源码调用分析第一个LayoutInflater.from(context);使用的源代码调用方法:
@SystemService(Context.LAYOUT_INFLATER_SERVICE)
公共抽象类LayoutInflater {
……
/**
* 从给定的上下文中获取LayoutInflater。
*/
公共静态LayoutInflater from(Context context) {
布局膨胀器布局膨胀器=
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
如果(LayoutInflater==null){
throw new AssertionError("LayoutInflater 未找到。");
}
返回布局膨胀器;
}
……
}第二个Activity中getLayoutInflater()调用的源码分析:
Activity.class源码:
公共类活动扩展. {
…………
@非空
公共LayoutInflater getLayoutInflater() {
返回getWindow().getLayoutInflater();
}
…………
@非空
公共LayoutInflater getLayoutInflater() {
返回getWindow().getLayoutInflater();
}
…………
最终无效附加(.){
.
mWindow=new PhoneWindow(this, 窗口, ActivityConfigCallback);
…………
}
…………
}
PhoneWindow源代码:
公共PhoneWindow(上下文上下文){
超级(上下文);
mLayoutInflater=LayoutInflater.from(context);
}查看源码可以发现:第一种调用的是第三种实例,第二种调用的是第一种实例,所以可以得到结果是:最终获取LayoutInflater都是通过第三种方式获取滴;
三、获取View : View.inflate()和LayoutInflate.inflater()
在项目中,经常需要将.xml布局文件转换为View。有两种方法:
1、使用View的静态方法inflate,而不获取LayoutInflater。其实源码里面也获取到了LayoutInflater:
查看源代码:
/**
* 从xml资源填充视图,该方法封装了LayoutInflater
* @param context 您的Activity 或应用程序上下文对象
* @param resouce 需要填写的资源ID
* @param root 视图组,将作为父视图组,用于正确填写布局参数
*/
公共静态视图膨胀(上下文上下文,@LayoutRes int资源,ViewGroup根){
LayoutInflater 工厂=LayoutInflater.from(context);
返回factory.inflate(资源,根);
}2.使用LayoutInflater.inflater():
调用方式有四种:
mLayoutInflater.inflate(@LayoutRes int 资源,@Nullable ViewGroup root);
mLayoutInflater.inflate(XmlPullParser解析器,@Nullable ViewGroup root);
mLayoutInflater.inflate(@Layoutres int Resource,@Nullable ViewGroup root,boolean AttachToRoot);
mLayoutInflater.inflater(XmlPullParser解析器,@Nullable ViewGroup root,boolean AttachToToot);查看以上四个方法的源码后发现,最终调用的是第四个方法;
在实际项目开发中,经常使用以下两种方法:
mLayoutInflater.inflate(@LayoutRes int 资源,@Nullable ViewGroup root);
mLayoutInflater.inflate(@Layoutres int resourse,@Nullable ViewGroup root, boolean AttachToRoot);您可以看到一个有两个参数,另一个有三个参数。两个参数的inflate实际上是调用的三个参数的inflate。现在我们来看看这三个参数的含义以及使用时需要注意的事项:
@LayoutRes int resource: 这显然是需要传入的布局的资源ID;
@Nullable ViewGroup root: 需要附加资源资源文件的父控件,即调用inflate方法会得到一个View对象,root参数是接受该对象的容器;
boolean attachToRoot: 是否将inflate得到的View对象添加到root中。当该参数为false时,表示不直接添加到root中。当为true 时,表示直接添加到根;
现在三个参数的含义已经清楚了,我们现在来了解一下用到的几个参数:
既然两个参数最终都是调用的三个参数方法,那先分析三个参数的inflate方法:现在定义您需要使用的布局文件:
Activity布局文件,Activity xml布局文件activity_main:只有一个空的Linearlayout
?xml 版本="1.0"编码="utf-8"?然后定义一个布局文件inflatelayout.xml用于填充:
?xml 版本="1.0"编码="utf-8"?1、root不为空,attachToRoot为true:在代码inflatelayout.xml 添加到我的Activity 布局:
@覆盖
protected void onCreate(Bundle savingInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll_root=(LinearLayout)findViewById(R.id.ll_root); //Activity的根布局
getLayoutInflater().inflate(R.layout.inflatelayout,ll_root,true); //填充布局
}查看项目运行结果:可以看到填充的布局已经添加到了activity中。这是因为第三个参数为true,表示将第一个参数所指的的布局添加到第二个参数的View中;
2、root不为空,attachToRoot为false:@覆盖
protected void onCreate(Bundle savingInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll_root=(LinearLayout)findViewById(R.id.ll_root);
查看视图=getLayoutInflater().inflate(R.layout.inflatelayout,ll_root,false);
ll_root.addView(视图);
}上面的代码实现了与attachToRoot为true时相同的操作效果。现在我们来分析一下当为false 时的情况:
AttachToRoot为false,表示第一个参数指定的布局文件不会添加到第二个参数的View中;这里就会有一个问题:既然不将布局文件添加到指定的root中,那为什么不直接将第二个参数给null?这又涉及到另一个问题:我们给控件所指定的layout_weight和layout_height到底是什么意思?该属性表示一个控件在容器中大小,就是说这个控件必须在容器中,这个属性才有意义,否则无意义!由此我们可以等到这个结论:如果我直接将inflatelayout.xml填充而不给他指定一个父布局,则inflatelayout.xml的根节点的高宽会失效,如果想让其有效,就必须为其指定一个父容器。现在我们可以在这里了解root和attachToRoot的作用:设置root不为空,是为了让inflatelayout.xml的根布局宽高有效,attachToRoot就是不自动将inflateLayout.xml填充到父容器中。3、root为空:其实,我们还将解释root 为空的两种情况。我在这里重复一下:root不为空,则填充的xml文件的根布局的宽高设置有效,attachToRoot决定是否将填充布局自动添加到root中; root为空,即不为填充控件指定父布局,这个时候attachToRoot无论是true还是false都是没有意义的!看下面的代码示例:
@覆盖
protected void onCreate(Bundle savingInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll_root=(LinearLayout)findViewById(R.id.ll_root);
查看视图=getLayoutInflater().inflate(R.layout.inflatelayout,null,false);
//视图view=getLayoutInflater().inflate(R.layout.inflatelayout,null,true);
ll_root.addView(视图);
}root为空,无论attachToRoot为true还是false,运行结果如下: 因为inflate时没有指定容器,所以宽度和高度无效,但是如果我设置了按钮的宽度和高度,就会有效,因为它在容器中;
现在分析两个参数的情况我们先看一下两个参数的调用源码:
公共视图膨胀(@LayoutRes int资源,@Nullable ViewGroup根){
返回膨胀(资源,根,根!=null);
}
公共视图膨胀(XmlPullParser解析器,@Nullable ViewGroup根){
return inflate(parser, root, root !=null);
可以清楚地看到,两个参数的inflate方法实际上调用了三个参数的inflate方法attchToRoot根据root来判断值,所以最终的结果分为以下两种情况:
root为null,相当于三个参数:root为空,attachToRoot为false; root不为null,相当于三个参数:root不为空,attachToRoot为true;以上就是对LayoutInflater和inflate方法的简单理解。使用介绍;
这里还有一个问题记录和分析:为什么Activity布局的根节点的宽高属性会生效?大多数Activity页面都是由两部分组成(Android版本号和应用主题会影响Activity页面的组成,这里以普通页面为例),我们的Activity页面有一个顶级View称为DecorView。 DecorView 包含一个垂直LinearLayout。线性布局由两部分组成。第一部分是标题栏,第二部分是内容栏。内容栏是一个FrameLayout。当我们在Activity中调用setContent时,我们将View添加到这个FrameLayout中。中间;
查看Activity中setContent源码:
@覆盖
公共无效setContentView(@LayoutRes intlayoutResID){
getDelegate().setContentView(layoutResID);
}
@覆盖
公共无效setContentView(int resId){
确保SubDecor();
ViewGroup contentParent=(ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mOriginalWindowCallback.onContentChanged();
【Android 系统中LayoutInflater的使用与概述】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
我最近在学习安卓开发,这个教程真是太棒了!
有15位网友表示赞同!
终于明白LayoutInflater的作用了,原来它可以很方便地生成View对象。
有11位网友表示赞同!
示例代码讲解得很清楚,一下子就理解了。
有13位网友表示赞同!
以前总是手写布局文件,现在用 LayoutInflater 一定效率更高啊。
有18位网友表示赞同!
这个教程介绍的实例应用场景很有帮助,让我能更直观地理解LayoutInflater的使用。
有20位网友表示赞同!
之前不知道Android有这么方便的工具,真是太实用了!
有9位网友表示赞同!
看来学习Android需要掌握好 LayoutInflater 这类实用工具了!
有13位网友表示赞同!
这个介绍很到位,从基础概念到具体使用都讲解得很全。
有14位网友表示赞同!
终于可以用LayoutInflater来快速创建View布局啦!
有6位网友表示赞同!
这篇教程帮助我解决了最近在开发中遇到的Inflate问题。
有12位网友表示赞同!
学习安卓开发的伙伴们,一定要看这篇文章!
有17位网友表示赞同!
这个网站真的很棒,总是能找到最新的Android开发教程和信息。
有9位网友表示赞同!
感谢作者分享这么有用的资源!
有18位网友表示赞同!
准备把这篇文章推荐给我的朋友们,他们也在学习Android开发.
有13位网友表示赞同!
看来以后开发中要用到 LayoutInflater 就先来复习一下这段教程。
有7位网友表示赞同!
真期待能把这些知识应用在实际项目中。
有5位网友表示赞同!
这个解释很简洁易懂,适合初学者学习!
有5位网友表示赞同!
我要去实践一下,看看LayoutInflater的使用效果!
有5位网友表示赞同!
Android开发的未来充满了可能性!
有6位网友表示赞同!