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

前言

两个都是布局加载器,而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


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何通过navicat连接SQL Server数据库

本文介绍如何通过Navicat 连接SQL Server数据库。如果想了解如何连接Oracle数据库&#xff0c;可以参考下边这篇文章。如何通过Navicat连接Oracle数据库https://sgknight.blog.csdn.net/article/details/132064235 1、新建SQL Server连接配置 打开Navicat软件&#xff0c;点击…

centos7安装Elasticsearch7系列

背景 今天公司项目需要使用Elasticsearch7.17.7。所有网上搜索了一番&#xff0c;查到一个很不错安装方式分享给大家。 Elasticsearch官网发布 从 Elasticsearch 7.x 版本开始&#xff0c;Elasticsearch 发行版包括了自己的 JDK。因此&#xff0c;您不需要单独安装 Java。以…

2023.2版idea安装教程,现在jdk8已经过去式了,不同idea支持的jdk不同。升级jdk后idea也要随之升级

下载idea2023.2版本&#xff0c;下载之前需要删除之前的版本&#xff0c;一定要删除干净&#xff0c;删除程序要勾选那两个delete 下载路径&#xff1a;其他版本 - IntelliJ IDEA (jetbrains.com.cn) 选择2023.2版本 下载后进入安装程序&#xff0c;选择安装目录&#xff0c;然…

去掉参数中第一个“,”

记录一下&#xff0c;前端传参中&#xff0c;传给我参数是“categoryIds: ,1731557494586241026,1731569816263311362,1731569855534579713,1731858335179223042,1731858366821052418” 但是后端&#xff0c;因为我的mybati是in查询&#xff0c;所以因为第一个是“,”。所以会导…

提升设备巡检效率的有效工具

易点易动设备管理系统是一款专注于提升设备巡检效率的高效工具。设备巡检是企业设备管理的重要环节&#xff0c;通过定期巡检设备&#xff0c;可以及时发现潜在问题&#xff0c;预防故障发生&#xff0c;确保设备安全运行。下面将介绍易点易动设备管理系统在设备巡检方面的功能…

Android 12.0 Folder文件夹全屏后文件夹图标列表居中时拖拽app到桌面的优化

1.概述 在12.0的系统rom产品开发中,在Launcher3中在目前的产品需求开发中,对于Launcher3中的文件夹Folder的布局UI 进行了定制化的需求要求把Folder修改为全屏,然后在中间显示文件夹图标的列表,这时候如果Folder是全屏的话,如果拖拽文件夹列表中的app图标,只有拖拽 到屏…

微服务学习(十三):安装Consul

微服务学习&#xff08;十三&#xff09;&#xff1a;安装Consul 一、简介 consul是分布式的、高可用、横向扩展的。 consul提供的一些关键特性&#xff1a; service discovery&#xff1a;consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易&#xff0c;一些外部服…

横向扩展统一存储与备份服务器功能

Infortrend 更新了GS&#xff0c;GSe&#xff0c;GSe Pro统一存储系列的备份服务器功能。该功能降低数据备份成本&#xff0c;并提供灵活的备份策略。通过备份服务器功能&#xff0c;用户可以通过多种途径实现数据备份&#xff0c;包括公有云&#xff08;兼容S3&#xff09;、文…

C# .NET平台提取PDF表格数据,并转换为txt、CSV和Excel表格文件

处理PDF文件中的内容是比较麻烦的事情&#xff0c;特别是以表格形式呈现的各种数据。为了充分利用这些宝贵的数据资源&#xff0c;我们可以通过程序提取PDF文件中的表格&#xff0c;并将其保存为更易于处理和分析的格式&#xff0c;如txt、csv、xlsx&#xff0c;从而更方便地对…

Stable Diffusion AI绘画系列【15】:花丛中的唯美人物写实照

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【Linux服务器Java环境搭建】07 在linux中安装MySql,以及对MySQL的配置与远程连接

【Linux服务器Java环境搭建】01购买云服务器以及在服务器中安装Linux系统 【Linux服务器Java环境搭建】02 通过xftp和xshell远程连接云服务器 【Linux服务器Java环境搭建】03 Git工具安装 【Linux服务器Java环境搭建】04 JDK安装&#xff08;JAVA环境安装&#xff09; 【Linux服…

jupyter notebook中添加内核kernel

step1 检查环境中是否有kernel python -m ipykernel --versionstep2 若没有kernel&#xff0c;则需要安装 kernel conda install ipykernel -i https://pypi.tuna.tsinghua.edu.cn/simplestep3 查看已添加的内核 jupyter kernelspec liststep4 添加内核 python -m ipykerne…

Vue3 pinia的基本使用

pinia的使用跟vuex很像&#xff0c;去除了很多没用的api&#xff0c;写法有两种&#xff0c;一种老式的选项式api还有一种组合式api&#xff0c;用哪种根据自己喜好来&#xff0c;以下示例为组合式api 更多教程参考官网&#xff1a;pinia官网https://pinia.vuejs.org/zh/ 安装…

鱼子酱产品供应商【富原集团】申请1380万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于香港的鱼子酱产品供应商富原集团(国际)有限公司&#xff08;Top Wealth Group Holding Ltd&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申…

react-router v6实现动态的title(react-router-dom v6)

前言 react-router-dom v6 默认不支持 title设置了&#xff0c;所以需要自己实现一下。 属性描述path指定路由的路径&#xff0c;可以是字符串或字符串数组。当应用的URL与指定的路径匹配时&#xff0c;该路由将会被渲染。element指定要渲染的React组件或元素。children代表…

TensoRF: Tensorial Radiance Fields

TensoRF: Tensorial Radiance Fields TensoRF是ECCV2022一个非常有特色的工作。作者在三维场景表示中引入张量分解的技术&#xff0c;将4D张量分解成多个低秩的张量分量&#xff0c;实现更好的重建质量、更快的重建速度、更小的模型体积。 文章目录 TensoRF: Tensorial Radian…

Chapter 6 Managing Application Engine Programs 管理应用程序引擎程序

Chapter 6 Managing Application Engine Programs 管理应用程序引擎程序 Running Application Engine Programs 运行应用程序引擎程序 This section provides an overview of program run options and discusses how to: 本节提供程序运行选项的概述&#xff0c;并讨论如何…

【已解决】MySQL:执行存储过程报错(MySQL字符集和排序方式冲突)

目录 问题现象&#xff1a; 问题分析&#xff1a; 解决方法&#xff1a; 拓展&#xff1a; 1、转换条件两边的字段或值为二进制数据&#xff1a; 2、转换条件两边的字段或值的字符集和排序方式&#xff1a; 3、修改列、表、库的字符集和排序方式 参考链接&#xff1a; 问…

基于Git的代码工程管理——学习记录一

一、Git简概[1] Git是一个分布式版本控制系统&#xff0c;它跟踪任何一组计算机文件的更改&#xff0c;通常用于在软件开发过程中协调协作开发源代码的程序员之间的工作。其为实现快速、数据完整性以及分布式非线性工作流程&#xff08;在不同计算机上运行数千个并行分支&#…

电脑上mp4视频文件无缩略图怎么办

前言&#xff1a;有时候电脑重装后电脑上的mp4视频文件无缩略图&#xff0c;视频文件数量比较多的时候查找比较麻烦 以下方法亲测有效&#xff1a; 1、下载MediaPreview软件 2、软件链接地址&#xff1a;https://pan.baidu.com/s/1bzVJpmcHyGxXNjnzltojtQ?pwdpma0 提取码&…