Android View.inflate 和 LayoutInflater.from(this).inflate的区别

news2024/11/25 18:56:10

前言

两个都是布局加载器,而View.inflate是对 LayoutInflater.from(context).inflate的封装,功能相同,案例使用了dataBinding。

View.inflate(context, layoutResId, root)

LayoutInflater.from(context).inflate(layoutResId, root, false)

区别

因为View.inflate(context,layoutResId,root)  LayoutInflater.from(context).inflate(layoutResId, root, attachToRoot) 少了一个attachToRoot参数(是否将layoutResId添加到父布局中的)。

在使用View.inflate(context,layoutResId,root) 时,如果root(父布局)是null,会导致layoutResId布局中声明的宽高 + 外边距参数,失效。

核心条件就是root(父布局)是不是null。

案例

1、使用View.inflate(context,layoutResId,root) root不为null

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));        
        setContentView(bind.getRoot());

        // 子布局:R.layout.app_layout_text    
        // 父布局:bind.box
        View.inflate(this,R.layout.app_layout_text,bind.box);
        View.inflate(this,R.layout.app_layout_text,bind.box);
        View.inflate(this,R.layout.app_layout_text,bind.box);

    }

2、使用LayoutInflater.from(context).inflate(layoutResId, root, attachToRoot)  root不为null,且attachToRoot是true

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));        
        setContentView(bind.getRoot());

        // 子布局:R.layout.app_layout_text    
        // 父布局:bind.box
        LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);
        LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);
        LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);

    }

两种方式效果相同,宽高 + 外边距都有效

3、使用View.inflate(context,layoutResId,root) root为 null

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));        
        setContentView(bind.getRoot());

        // 子布局:R.layout.app_layout_text    
        // 父布局:bind.box
        View view = View.inflate(this, R.layout.app_layout_text, null);
        View view2 = View.inflate(this, R.layout.app_layout_text, null);
        View view3 = View.inflate(this, R.layout.app_layout_text, null);
        bind.box.addView(view);
        bind.box.addView(view2);
        bind.box.addView(view3);
    }

4、使用LayoutInflater.from(context).inflate(layoutResId, root, attachToRoot)  root为 null,且attachToRoot是false

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));        
        setContentView(bind.getRoot());

        // 子布局:R.layout.app_layout_text    
        // 父布局:bind.box
        View view = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        View view2 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        View view3 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        bind.box.addView(view);
        bind.box.addView(view2);
        bind.box.addView(view3);
    }

两种方式效果相同,宽高 + 外边距都失效了

5、如果不想将view添加到父布局中,同时又不想丢失layoutResId布局声明的参数,LayoutInflater.from(context).inflate(layoutResId, root, attachToRoot)这样写可以做到,root不为null,但是attachToRootfalse

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));        
        setContentView(bind.getRoot());

        // 子布局:R.layout.app_layout_text    
        // 父布局:bind.box
        View view = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        View view2 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        View view3 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        bind.box.addView(view);
        bind.box.addView(view2);
        bind.box.addView(view3);
    }

效果

6、而View.inflate(context,layoutResId,root) 目前为止无法做到,因为它少了一个attachToRoot参数(是否将layoutResId添加到父布局中的),以后说不准会有这个参数的重载方法。

7、案例文件:shape_border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:color="@color/color_303133" android:width="1dp"/>
</shape>

8、案例文件:app_layout_text.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="200dp"
    android:layout_marginBottom="20dp"
    android:background="@drawable/shape_border"
    android:paddingLeft="20dp"
    android:paddingTop="50dp"
    android:text="测试" />

9、案例文件:app_activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <LinearLayout
        android:id="@+id/box"
        android:orientation="vertical"
        android:background="@color/color_14F9230A"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>

</layout>

10、案例文件:AppMainActivity.Java

public class AppMainActivity extends AppCompatActivity {

    private AppActivityMainBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bind = AppActivityMainBinding.bind(getLayoutInflater().inflate(R.layout.app_activity_main,null));
        setContentView(bind.getRoot());

        // View.inflate(this,R.layout.app_layout_text,bind.box);
        // View.inflate(this,R.layout.app_layout_text,bind.box);
        // View.inflate(this,R.layout.app_layout_text,bind.box);

        // View view = View.inflate(this, R.layout.app_layout_text, null);
        // View view2 = View.inflate(this, R.layout.app_layout_text, null);
        // View view3 = View.inflate(this, R.layout.app_layout_text, null);
        // bind.box.addView(view);
        // bind.box.addView(view2);
        // bind.box.addView(view3);


        // LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);
        // LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);
        // LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);

        // View view = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        // View view2 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        // View view3 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);
        // bind.box.addView(view);
        // bind.box.addView(view2);
        // bind.box.addView(view3);

        // View view = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        // View view2 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        // View view3 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, null, false);
        // bind.box.addView(view);
        // bind.box.addView(view2);
        // bind.box.addView(view3);

}

源码解析

View.inflate源码,还是调用的LayoutInflater.from(context).inflate

    public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
        LayoutInflater factory = LayoutInflater.from(context);
        return factory.inflate(resource, root);
    }

LayoutInflater.java源码

第一判断条件是root(父布局)是否为null,第二判断条件就是attachToRoot,View.inflate没有这个参数。

    ... ... 

    View result = root;

    ... ... 

    if (root != null) {
        // Create layout params that match root, if supplied
        params = root.generateLayoutParams(attrs);
        if (!attachToRoot) {
            // Set the layout params for temp if we are not
            // attaching. (If we are, we use addView, below)
            temp.setLayoutParams(params);
        }
    }

    ... ... 

    return result;

总结

只有在实例化布局时,而又不想将view添加到父布局中,和不想丢失layoutResId布局声明的参数的情况下,它俩才会有使用区别。

顺便说一下返回值,将当前布局添加到父布局中时,返回的是父布局View,反之返回的是当前布局View,这一点他们是一样的。


         View view = View.inflate(this, R.layout.app_layout_text, bind.box);

         Log.d("TAG","父布局LinearLayout:"+(view instanceof LinearLayout)); // true
         Log.d("TAG","当前布局TextView:"+(view instanceof TextView)); // false

         View view2 = View.inflate(this, R.layout.app_layout_text, null);

         Log.d("TAG","父布局LinearLayout:"+(view2 instanceof LinearLayout)); // false
         Log.d("TAG","当前布局TextView:"+(view2 instanceof TextView)); // true




         View view3 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, true);

         Log.d("TAG", "父布局LinearLayout:" + (view3 instanceof LinearLayout)); // true
         Log.d("TAG", "当前布局TextView:" + (view3 instanceof TextView)); // false

         View view4 = LayoutInflater.from(this).inflate(R.layout.app_layout_text, bind.box, false);

         Log.d("TAG", "父布局LinearLayout:" + (view4 instanceof LinearLayout)); // false
         Log.d("TAG", "当前布局TextView:" + (view4 instanceof TextView)); // true


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1287585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CLIP在Github上的使用教程

CLIP的github链接&#xff1a;https://github.com/openai/CLIP CLIP Blog&#xff0c;Paper&#xff0c;Model Card&#xff0c;Colab CLIP&#xff08;对比语言-图像预训练&#xff09;是一个在各种&#xff08;图像、文本&#xff09;对上进行训练的神经网络。可以用自然语…

JS箭头函数

箭头函数 1. 基本语法 // // 一般函数const fn function() {console.log(123);}// 箭头函数const fn () > {console.log(123);}fn()const fn (x) > {console.log(x);}fn(1)// 只有一个形参的时候可以省略小括号const fn x > {console.log(x);}fn(1)// 只有一行代…

基于c++版本链队列改-Python版本链队列基础理解

##基于链表的队列实现 可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”&#xff0c;规定队尾仅可添加节点&#xff0c;队首仅可删除节点。 ##图解 ##基于链表的队列实现代码 class ListNode:"""定义链表"""def __init__(self)…

nodejs微信小程序+python+PHP本科生优秀作业交流网站的设计与实现-计算机毕业设计推荐

通过软件的需求分析已经获得了系统的基本功能需求&#xff0c;根据需求&#xff0c;将本科生优秀作业交流网站功能模块主要分为管理员模块。管理员添加系统首页、个人中心、用户管理、作业分类管理、作业分享管理、论坛交流、投诉举报、系统管理等操作。 随着信息化社会的形成…

Mybatis XML 配置文件

我们刚开始就有说Mybatis 的开发有两种方式: 1.注释 2.XML 注解和 XML 的方式是可以共存的 我们前面说的都是注释的方式,接下来是XML方式 XML的方式分为三步 : 1.配置数据库(配在 application.yml 里面) 这个跟注释的配置是一样的,username应该都是一样的,password记得写…

git常用命令指南

目录 一、基本命令 1、创建分支 2、切换分支 3、合并分支 4、初始化空git仓库 二、文件操作 1、创建文件 2、添加多个文件 3、查看项目的当前状态 4、修改文件 5、删除文件 6、提交项目 三、实际操作 1、创建目录 2、进入新目录 3、初始化空git仓库 4、创建文…

【OpenGauss源码学习 —— (RowToVec)算子】

VecToRow 算子 概述ExecInitRowToVec 函数ExecRowToVec 函数VectorizeOneTuple 函数 ExecEndRowToVec 函数总结 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在…

使用AWS Glue与AWS Kinesis构建的流式ETL作业(二)——数据处理

大纲 2 数据处理2.1 架构2.2 AWS Glue连接和创建2.2.1 创建AWS RedShift连接2.2.2 创建AWS RDS连接&#xff08;以PG为例&#xff09; 2.3 创建AWS Glue Job2.4 编写脚本2.4.1 以AWS RedShift为例2.4.2 以PG为例 2.5 运行脚本 2 数据处理 2.1 架构 2.2 AWS Glue连接和创建 下…

DSSS技术和OFDM技术

本内容为学习笔记&#xff0c;内容不一定正确&#xff0c;请多处参考进行理解 https://zhuanlan.zhihu.com/p/636853588 https://baike.baidu.com/item/OFDM/5790826?frge_ala https://zhuanlan.zhihu.com/p/515701960?utm_id0 一、 DSSS技术 信号替代&#xff1a;DSSS技术为…

谈一谈内存池

文章目录 一&#xff0c;什么是内存池二&#xff0c;进程地址空间中是如何解决内存碎片问题的三&#xff0c;malloc的实现原理四&#xff0c;STL中空间配置器的实现原理五&#xff0c;高并发内存池该内存池的优势在哪里内存池的设计框架内存申请流程ThreadCache层CentreCache层…

论文阅读:一种通过降低噪声和增强判别信息实现细粒度分类的视觉转换器

论文标题&#xff1a; A vision transformer for fine-grained classification by reducing noise and enhancing discriminative information 翻译&#xff1a; 一种通过降低噪声和增强判别信息实现细粒度分类的视觉转换器 摘要 最近&#xff0c;已经提出了几种基于Vision T…

Linux 中用户与权限

1.添加用户 useradd 1&#xff09;创建用户 useradd 用户名 2&#xff09;设置用户密码 passwd 用户名 设置密码是便于连接用户时使用到&#xff0c;如我使用物理机链接该用户 ssh 用户名 ip 用户需要更改密码的话&#xff0c;使用 passwd 指令即可 3)查看用户信息 id 用…

【数据结构(六)】希尔排序、快速排序、归并排序、基数排序的代码实现(3)

文章目录 1. 希尔排序1.1. 简单插入排序存在的问题1.2. 相关概念1.3. 应用实例1.3.1. 交换法1.3.1.1. 逐步推导实现方式1.3.1.2. 通用实现方式1.3.1.3. 计算时间复杂度 1.3.2. 移动法 2. 快速排序2.1. 相关概念2.2. 实例应用2.2.1. 思路分析2.2.2. 代码实现 2.3. 计算快速排序的…

Spatial Data Analysis(三):点模式分析

Spatial Data Analysis&#xff08;三&#xff09;&#xff1a;点模式分析 ---- 1853年伦敦霍乱爆发 在此示例中&#xff0c;我将演示如何使用 John Snow 博士的经典霍乱地图在 Python 中执行 KDE 分析和距离函数。 感谢 Robin Wilson 将所有数据数字化并将其转换为友好的 G…

(04730)电路分析基础之电阻、电容及电感元件

04730电子技术基础 语雀&#xff08;完全笔记&#xff09; 电阻元件、电感元件和电容元件的概念、伏安关系&#xff0c;以及功率分析是我们以后分析电 路的基础知识。 电阻元件 电阻及其与温度的关系 电阻 电阻元件是对电流呈现阻碍作用的耗能元件&#xff0c;例如灯泡、…

基于STM32驱动的压力传感器实时监测系统

本文介绍了如何使用STM32驱动压力传感器进行实时监测。首先&#xff0c;我们会介绍压力传感器的工作原理和常见类型。然后&#xff0c;我们将介绍如何选择合适的STM32单片机和压力传感器组合。接下来&#xff0c;我们会详细讲解如何使用STM32驱动压力传感器进行数据采集和实时监…

根文件系统软件运行测试

一. 简介 前面几篇文章学习了制作一个可以在开发板上运行的&#xff0c;简单的根文件系统。 本文在上一篇文章学习的基础上进行的&#xff0c;文章地址如下&#xff1a; 完善根文件系统-CSDN博客 本文对根文件系统软件运行进行测试。 我们使用 Linux 的目的就是运行我们自…

vue3 setup语法糖 多条件搜索(带时间范围)

目录 前言&#xff1a; setup介绍&#xff1a; setup用法&#xff1a; 介绍&#xff1a; 前言&#xff1a; 不管哪个后台管理中都会用到对条件搜索带有时间范围的也不少见接下来就跟着我步入vue的多条件搜索&#xff08;带时间范围&#xff09; 在 Vue 3 中&#xff0c;你…

[JavaScript前端开发及实例教程]计算器井字棋游戏的实现

计算器&#xff08;网页内实现效果&#xff09; HTML部分 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>My Calculator&l…

Unity3D对CSV文件操作(创建、读取、写入、修改)

系列文章目录 Unity工具 文章目录 系列文章目录前言一、Csv是什么&#xff1f;二、创建csv文件2-1、构建表数据2-2、创建表方法2-3、完整的脚本&#xff08;第一种方式&#xff09;2-4、运行结果2-5、完整的脚本&#xff08;第二种方式&#xff09;2-6、运行结果2-7、想用哪种…