Android 中LayoutInflater(布局加载器)之介绍篇

473 阅读5分钟
本文出自博客Vander丶CSDN博客,如需转载请标明出处,尊重原创谢谢
博客地址:blog.csdn.net/l540675759/…

前言

如果读者没有阅读过该系列博客,建议先阅读下博文说明,这样会对后续的阅读博客思路上会有一个清晰的认识。

Android 中LayoutInflater(布局加载器)系列博文说明

本篇作为Android 中LayoutInflater(布局加载器)系列的介绍篇,该篇内容知识内容比较基础,建议先看一些概述,如果感觉OK,可以直接跳过该章节,直接查看源码分析篇。

Android 中LayoutInflater(布局加载器)系列之源码篇


导航

Android 中LayoutInflater(布局加载器)系列博文说明

Android 中LayoutInflater(布局加载器)系列之介绍篇

Android 中LayoutInflater(布局加载器)系列之源码篇

Android 中LayoutInflater(布局加载器)源码篇之createViewFromTag方法

Android 中LayoutInflater(布局加载器)源码篇之rInflate方法

Android 中LayoutInflater(布局加载器)系列之实战篇


概述

(1)LayoutInflater的常见使用场景

(2)LayoutInflater的介绍

(3)LayoutInflater相关介绍中的相关概念分析


LayoutInflater的常见使用场景

在介绍之前,我们先回一下,我们在哪些地方都使用过LayoutInflater:

(1)在Activity中

        LayoutInflater inflater = getLayoutInflater();
        View view = inflater.inflate(R.layout.activity_main, null);

(2)在Fragment中

        View view = inflater.inflate(R.layout.fragment_guide_one, container, false);
        return view;

(3)在Adapter中

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = LayoutInflater.from(convertView.getContext()).inflate(R.layout.activity_main, parent, false);
        return view;
    }

(4)在某些特殊情况下,需要使用LayoutInflater,我们是这样获得它的

        LayoutInflater inflater  =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

上述的使用,是我们平常常见的使用方式,而这些场景都有一个特点,因为这些场景都需要将一个XML布局文件转化成View,所以准确的说LayoutInflater的主要功能来说就是布局加载

其实LayoutInflater还有一些扩展操作,可以通过我们自定义的方式来实现,在后面的实战篇会介绍。

这里写图片描述
这里写图片描述


LayoutInflater的介绍

对于LayoutInflater的介绍性质的内容,博主认为,在网上查的任何内容,都不如查阅源码,API来的靠谱一些,因为API才是第一手的介绍资料,而且Android的源码中介绍的也比较完善。

LayoutInflater属于 android.view包下,在LayoutInflater的头部有一段关于LayoutInflater的介绍:

LayoutInflater的介绍源码
LayoutInflater的介绍源码

由于篇幅原因,这里只截取了一部分图片,总结一下:

(1)LayoutInflater的主要作用将XML文件实例化成相应的View对象

(2)LayoutInflater在Android开发过程中,获取的方式不是直接new出来的,都是经过这两个方法得到的关联上下文的LayoutInflater:

//在Activity中
LayoutInflater inflater = Activity#getLayoutInflater()
//其他情况
LayoutInflater inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)

(3)如果想使用新的LayoutInflater来加载View,需要使用cloneInContext(),而在新的LayoutInflater需要调用setFactory()设置视图处理器

(4)由于性能的原因,XML文件的预处理是在Build过程中进行的。

(5)LayoutInflater不能加载未编译的XML文件,而且LayoutInflater只能加载,通过XmlPullParser解析的R文件资源

懵逼的眼神
懵逼的眼神


LayoutInflater介绍相应的解释

经过上面的总结,大家对LayoutInflater有一个大致的认识,为了大家不是太懵逼,让我一一解释一波。

(1)LayoutInflater的主要作用将XML文件实例化成相应的对象

其实,大家在使用LayoutInflater时,也会注意到无非就是将布局资源通过LayoutInflater转换为相对应的View,然后在进行一些其他操作,就是LayoutInflater常见场景中的几种情况:

        View view = inflater.inflate(R.layout.fragment_guide_one, container, false);
        return view;

(2)LayoutInflater在Android开发过程中,不是通过new出来获取到的?

在上述场景中,除了介绍的两种方式Activity#getLayoutInflater(),以及getSystemService(),大家发现常见场景中还使用了

LayoutInflater inflater =LayoutInflater.from(convertView.getContext());

其实LayoutInflater.from()这个方法是官方帮我们封装了一层而已,底层还是调用getSystemService()方法,目的是使LayoutInflater与Context对象相绑定:

    public static LayoutInflater from(Context context) {
        LayoutInflater LayoutInflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (LayoutInflater == null) {
            throw new AssertionError("LayoutInflater not found.");
        }
        return LayoutInflater;
    }

(3)如果想使用新的LayoutInflater来加载,需要使用cloneInContext(),而在新的LayoutInflater需要调用setFactory()设置视图处理器

正常来说,这种使用方式的使用场景现在也是比较多的,比如:

  1. 批量获取XML中自定义的属性
  2. 动态换肤的效果
  3. 动态改变布局中的元素

这些都是通过LayoutInflater中的Factory来实现的,而介绍这部分内容会在实战篇来介绍。

(4)由于性能的原因,XML文件的预处理是在Build过程中进行的

举个例子,在编写XML布局资源时,如果漏写了结束符号,或者一些奇怪的操作,在运行程序之前的Build(构建阶段),就会弹出报错。

这里故意将结束符,写错

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="20sp" /

这里就会收到报错信息提示,每个XML都会有一个预编译的过程,这个过程发生在构建阶段(Build),而不是运行时。

XML报错信息
XML报错信息

(5)LayoutInflater只能加载通过XmlPullParser解析的R文件资源

这里的R文件资源就是指这些资源文件

例如:

R.layout.xxxx
R.drawable.xxxx
R.color.xxx
R.string.xxx

而LayoutInflater的作用将这些资源转化为实际的Android的对象,在源码篇会分析这个过程的实现。