•她的第一次

  话说,那是一个风雪交加的夜晚,看着她独自一个人走在漆黑的小道上,我抓紧跟了过去;

  那晚,我们......

  记得第一次接触这个 Layoutinflater 应该是在学习 ListView 的时候;

  在为 ListView 添加适配器 Adapter 的时候,会用到这个;

  当时也是大致了解了一下它的作用,今天有空,就让我们来深入了解一下;

•她知他长短

Layoutinflater与findViewById的恩怨情仇

  LayoutInflater 是用来找 layout 下  .xml 布局文件,并且实例化;

  而findViewById()是找具体  .xml  下的具体 widget控件:

  • Button mBtn = findViewById(R.id.btn);
  • TextView mTv = findViewById(R.id.tv);
  • ......

  对于一个没有被载入或者想要动态加载的界面,都需要使用 LayoutInflater.inflate() 来载入。

  什么叫做动态加载的界面呢?

动态加载界面

  修改 activity_main.xml 中的代码;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="动态添加子布局"
android:textSize="30sp"
/>
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:orientation="vertical"> </LinearLayout>
</LinearLayout>

  在该布局中,天机了一个 <TextView> 用于显示一行文字;

  并添加了一个  android:id 为 layout 的 <LinearLayout>,该 LinearLayout 中未添加任何控件;

  接下来我们就尝试动态向该 LinearLayout 中添加控件;

  在 layout 下新建一个子布局文件 layout_item.xml,并添加如下代码;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:gravity="center"> <View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/black"/>
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/green"/> </LinearLayout>

  该布局也是非常的简单,就是两块涂满颜色的 <View>;

  修改 MainActivity.java 中的代码,将该布局添加到 layout 中;

public class MainActivity extends AppCompatActivity {

    private LinearLayout mLinearLayout;//对应于主布局中用来添加子布局的View
private View mView;// 子Layout要以view的形式加入到主Layout
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mLinearLayout = findViewById(R.id.layout);
mLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mView = View.inflate(MainActivity.this,R.layout.layout_item,null);
if(v.getId() == R.id.layout){
mLinearLayout.addView(mView);
}
}
});
}
}

  分析一下该代码:

  • 首先,通过 findViewById() 找到 layout
  • 接着,为 layout 设置点击事件
  • 在该点击事件中,通过 View 的  inflate() 方法动态加载 layout_item 布局
  • 最后,通过  addView() 方法将 layout_item 加载到 layout 中

  让我们来看看运行效果:

  是不是添加成功了?

  不知道你有没有发现一个问题,在 layout_item.xml 中设置的 layout_width 和 layout_height 都是 200dp;

  为什么在 layout 中显示的是 match_parent 呢?

  欲知后事如何,请听下回分解。

•他知她深浅

  休息是不可能休息的,接着上课;

参数类型

  接下来看一下 LayoutInflater 中的 inflate() 的用法;

  该方法接收三个参数(int resource, ViewGroup root, boolean attachToRoot):

  • resource:需要加载布局文件的 id

    • 意思是需要将这个布局文件中加载到Activity中来操作。
  • root:需要附加到 resource 资源文件的根控件

    • 什么意思呢,就是  inflate()  方法会返回一个 View 对象
    • 如果第三个参数 attachToRoot 为 true,就将这个 root 作为根对象返回
    • 否则仅仅将这个root对象的 LayoutParams 属性附加到 resource 对象的根布局对象上
    • 也就是布局文件 resource 的最外层的 View 上
  • attachToRoot:是否将root附加到布局文件的根视图上

编写代码

  下面,我们通过代码来直观感受一下;

  修改 activity_main.xml 中的代码;

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

  对这个布局是不是很眼熟;

  同样,为 <LinearLayout> 设置了  android:id 属性;

  接下来我们还是动态向该 <LinearLayout> 中添加布局,就用上面的 layout_item 布局吧;

  修改 MainActivity.java 中的代码;

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); LinearLayout ll = findViewById(R.id.main_layout);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this); View view = inflater.inflate(R.layout.layout_item, ll,true);
}
}

   inflate()  方法返回的是一个 View,而我并没有添加这个返回的 View;

  为什么就已经将 layout_item 添加进来了呢?

  因为我的第三个参数设置为 true,表示将第一个参数所指定的布局添加到第二个参数的 View 中。

运行结果

  

  有没有发现,layout_item.xml 中的 layout_weight 和 layout_height 生效了?

踩坑

  如果我们在最后额外添加  ll.addView(view); ,运行的时候将会报错;

  意思大概是重复添加子项布局;

  原因就是因为当第三个参数为 true 时,会自动将第一个参数所指定的 View 添加到第二个参数所指定的 View 中。

设置attachToRoot为false

  下面我们再来看看当第三个参数 attachToRoot 为 false 时的情况;

  当 attachToRoot 为 false 时,表示不将第一个参数所指定的 View 添加到第二个参数 root 中去。

  因为我们想要添加布局可以把第三个参数设为 true,那我们为什么这里要设为 false 呢?

  我们在设置控件的时候,都会设置 layout_width 和 layout_height,这两个属性表示的是在容器里的大小;

  当然也意味着,这两个属性必须要在容器里才有意义,否则没有意义。

  这就意味着如果我直接将 layout_item 加载进来而不给它指定一个父布局;

  则 inflate 布局的根节点的 layout_width 和 layout_height 属性将会失效;

  还是通过代码来直观感受,修改 MainActivity.java 中的代码;

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); LinearLayout ll = findViewById(R.id.main_layout);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this); // 重复添加布局,报错
// View view = inflater.inflate(R.layout.layout_item, ll,true);
// ll.addView(view); //layout_item 中的 layout_width和layout_height属性将会失效
View view = inflater.inflate(R.layout.layout_item,null);
ll.addView(view);
}
}

运行结果

  

  是不是失效了?

设置attachToRoot为false并添加root

  如果我想让 layout_item 的根节点有效,又不想让其处于某一个容器中;

  那我就可以设置 root 不为 null,而 attachToRoot 为 false。

  接着修改 MainActivity.java 中的代码;

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); LinearLayout ll = findViewById(R.id.main_layout);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this); // 重复添加布局,报错
// View view = inflater.inflate(R.layout.layout_item, ll,true);
// ll.addView(view); //layout_item 中的 layout_width和layout_height属性将会失效
// View view = inflater.inflate(R.layout.layout_item,null);
// ll.addView(view); View view = inflater.inflate(R.layout.layout_item,ll,false);
ll.addView(view);
}
}

运行结果

  

Android学习之Layoutinflater的用法的更多相关文章

  1. android学习9——Handler简单用法

    Handler用来发消息和处理消息.典型的用法是更新界面.android不允许在子线程里面更新界面,通常是把Handler传到子线程中,在子线程里通过sendEmptyMessage函数发消息.Han ...

  2. [Android学习笔记]LayoutInflater的使用

    LayoutInflater用于动态载入布局,然后获取到布局中定义完成的控件引用 常在动态加载布局,和Adapter中用到 使用步骤:1.通过LayoutInflater加载xml布局文件2.从载入的 ...

  3. Android学习笔记_72_Spinner的用法

    一.普通 1. <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android= ...

  4. 十、Android学习第九天——小结(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 十.Android学习第九天——小结 通过这段时间的学习,今晚上来做个小小 ...

  5. Android学习第三天-打包常用命令

    在前面<Android学习第一天-adb常用命令>和 <Android学习第二天-android常用命令>两篇博文中,我们重点讲解了adb和android的常用命令,下面我们讲 ...

  6. 【Android学习】《Android开发视频教程》第一季笔记

    视频地址: http://study.163.com/course/courseMain.htm?courseId=207001 课时5    Activity基础概念 1.Android开发技术结构 ...

  7. Android学习随笔--ListView的分页功能

    第一次写博客,可能格式,排版什么的会非常不美观,不过我主要是为了记录自己的Android学习之路,为了以后能有些东西回顾.既然是为了学习,那我肯定会吸收各位大大们的知道经验,有不足的地方请指出. 通过 ...

  8. android学习日记03--常用控件Dialog

    常用控件 9.Dialog 我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框 对话框,要创建对话框之前首先要创建Bui ...

  9. android学习日记03--常用控件checkbox/radiobutton

    常用控件3.checkbox 复选框,确定是否勾选,点击一下勾选,点击第二下取消,当有一系列备选项时适合用checkbox控件,方便用户提交数据. 贴上例子Activity的java代码 packag ...

随机推荐

  1. API 授权 All In One

    API 授权 All In One 身份验证 授权类型 身份验证类型 继承认证 没有认证 API密钥 不记名令牌 基本认证 摘要授权 OAuth 1.0 OAuth 2.0 授权码 隐含的 密码凭证 ...

  2. WebXR All in One

    WebXR All in One VR / WebVR WebXR https://www.w3.org/TR/webxr/ WebXR Device API https://immersiveweb ...

  3. Java Hipster

    Java Hipster JHipster JHipster is a development platform to quickly generate, develop, & deploy ...

  4. npm install 原理

    npm install 原理 https://docs.npmjs.com/about-npm/ npm consists of three distinct components: the webs ...

  5. 比特币等主流货币走势成谜,VAST深受关注

    谁也不会想到,2021年的第一个月份,数字货币市场就会如此精彩.先是以比特币为首的主流货币迎来了一波上涨,让很多生态建设者看到了暴富的机会.再是一波大跌,让很多建设者失去了希望.再到后来触底反弹和冲高 ...

  6. 知名金融媒体采访行业大咖,多方推动BGV茁壮成长

    近来,多家知名金融媒体如纽约金融时报.伦敦金融时报等采访NGK官方代表洛索斯夫,以及美国当地行业大咖马库斯等人. 受访的NGK官方代币洛索斯夫回答道,近期官方将会推出NGK的书籍<NGK公链底层 ...

  7. NGK Global莫斯科路演:关注内存暴涨和Defi新项目-Baccarat

    此次路演由莫斯科演讲师Andrew首先致辞.首先安德鲁回顾了NGK近些年发展的整体情况,表示,NGK技术团队一直在认真的做事并将更加注重技术方案的改进,为行业提供更好的技术解决方案是NGK的愿景,NG ...

  8. Nice!JavaScript基础语法知识都在这儿了

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star 转载请注明出处! 链接:https://blog.csdn ...

  9. 纯js日历插件

    成品的效果图 1.HTML文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  10. 使用 Tye 辅助开发 k8s 应用竟如此简单(四)

    续上篇,这篇我们来进一步探索 Tye 更多的使用方法.本篇我们来了解一下如何在 Tye 中如何进行日志的统一管理. Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架.如果您是首 ...