Android 性能优化 三 布局优化ViewStub标签的使用

小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用

小白:Hi,小黑,ViewStub是什么?听说可以用来进行布局优化。

小黑:ViewStub 是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。(更多详细的API等信息可以查看官方文档ViewStub),计算机行业一向是实践里面出真知,下面用一个例子演示下效果。

小黑:说说概念只是为了概括性的了解下,还是用个实例来演示下。先来创建一个Activity中使用的布局文件,文件名是:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/show_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示"/>

    <ViewStub
        android:id="@+id/viewstub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/sub_layout"
        />

    <Button
        android:id="@+id/hide_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="隐藏"/>

</LinearLayout>

小白:“显示”、“隐藏”字符串没有放入values/string.xml,控件的id也没有一定的命名规则的乱起。

小黑:。。。。。。“你是猴子请来的救兵吗?”,一切从简好吧。注意上面的ViewStub的用法,其中android:layout="@layout/sub_layout"引入一个新的布局,sub_layout.xml代码如下:

<TextView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textview"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="ViewStub中包含的TextVeiw"/>

小白:现在有两个布局文件了,一个是Activity setContentView需要的activity_main.xml,一个是其中引入的sub_layout

小黑:下面是一个MainActivity.java,添加些点击事件

package com.example.viewstub;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewStub;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          final ViewStub viewStub = (ViewStub) findViewById(R.id.viewstub);

          View showButton = findViewById(R.id.show_button);
          showButton.setOnClickListener(new OnClickListener() {

               @Override
               public void onClick(View v) {
                    viewStub.inflate();
               }
          });

          View hideButton = findViewById(R.id.hide_button);
          hideButton.setOnClickListener(new OnClickListener() {

               @Override
               public void onClick(View v) {
                    viewStub.setVisibility(View.GONE);
               }
          });
     }
}

小黑:下面是代码运行后,默认并没有点击显示按钮的情况下,使用“DDMS -> Dump View Hierarchy for UI Automator”工具的截图

小白:我发现activity_main.xml布局文件在“显示”,“隐藏”两个按钮之间有一个<ViewStub>而在上面的截图中并没有,说明ViewStub在初始化加载时并不会添加到视图树上(Android UI Tree)。我也使用“Hierarchy View”工具的截图如下:

小黑:对,这是ViewStub可以进行布局优化的地方“懒加载视图”,初始化时系统不会初始化ViewStub引用的视图。再来看下接着看下点击“显示”按钮后的截图。

小黑:ViewStub使用流程是 1. 布局中添加ViewStub (XML添加、代码中添加) 2. inflate显示 3. setVisibility隐藏。

小白:通过在代码中viewStub.inflate(); ViewStub引用的布局显示出来了。不过,这不就是动态的添加视图吗?与View.setVisibility(View.GONE);有啥区别?

小黑:ViewStub是一个没有尺寸大小并且不会在布局中嵌套或渲染任何东西的轻量级的视图。因此在视图层次展现或隐藏它的代价非常小。当ViewStub可见,或者调用 inflate()函数时,才会加载这个布局资源文件。 该ViewStub在加载视图时在父容器中替换它本身。因此,ViewStub会一直存在于视图中,直到调用setVisibility(int) 或者inflate()为止。ViewStub的布局参数会随着加载的视图数一同被添加到ViewStub父容器。同样,你也可以通过使用inflatedId属性来定义或重命名要加载的视图对象的Id值。

View.setVisibility(View.GONE); 方式在初始化时就会添加到视图树上(Android UI Tree),而使用ViewStub在初始化时不会添加。

小白:使用ViewStub有啥需要注意的吗?

小黑:1. 在要渲染的布局中并不支持<merge/>标签。 2. ViewStub.infalte方法不能调用两次,否者会出现以下异常:

java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent
     at android.view.ViewStub.inflate(ViewStub.java:287)
     at com.example.viewstub.MainActivity$1.onClick(MainActivity.java:23)
     at android.view.View.performClick(View.java:4475)
     at android.view.View$PerformClick.run(View.java:18786)
     at android.os.Handler.handleCallback(Handler.java:730)
     at android.os.Handler.dispatchMessage(Handler.java:92)
     at android.os.Looper.loop(Looper.java:176)
     at android.app.ActivityThread.main(ActivityThread.java:5419)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:525)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
     at dalvik.system.NativeStart.main(Native Method)

小白:在网上看的资料说是ViewStub的一个缺点是引入的布局不能使单独的视图,而必须是一个布局才行,是这样吗?

小黑:这种观点是错误的,在例子sub_layout.xml 中仅有一个TextView视图。

小白:为什么ViewStub可以作为一个布局标签使用?

小黑:你可以查看一下ViewStub的源码,public
final class ViewStub extends View, ViewStub本身就是一个View 子类。

小白:我有几个问题:

1. ViewStub添加的视图可以动态删除吗?

2. 不能第二次inflate为什么?

3. 虽然第二次不能直接inflate,可以直接删除,代码中添加视图吗?

4. 除了调用inflate方法还能通过其他方式显示出来吗?(找到id 设置visible)

小黑:偶不知道啊。。。

参考资料

ViewStub - 官方文档

Loading Views On Demand - 官方教程

Android Layout Tricks #3: Optimize with stubs - 官方博客

Android学习笔记31:使用惰性控件ViewStub实现布局动态加载

性能优化之布局优化

更多优化相关的文章详见:《Android 基础学习文章汇总》 第三部分 性能优化

Android 性能优化 三 布局优化ViewStub标签的使用,布布扣,bubuko.com

时间: 2024-10-06 00:41:07

Android 性能优化 三 布局优化ViewStub标签的使用的相关文章

Android性能优化之布局优化

由于Android系统对硬件的要求较高,并且上层应用都是用Java(效率要比C++低)编写的,对程序的优化就成了程序员的日常工作了:Android的优化 可以从以下几个地方下手:布局优化.数据库优化.使用异步加载数据.使用缓存技术.算法代码优化.使用线程池 先从比较简单的布局入手 程序目录结构 1.使用 <include>标签复用相同部分的布局文件,就是在一個而已文件中包含另一个布局 activity_main.xml <RelativeLayout xmlns:android=&quo

【转】Android性能优化之布局优化篇

转自:http://blog.csdn.net/feiduclear_up/article/details/46670433 Android性能优化之布局优化篇 分类: andorid 开发2015-06-29 16:28 238人阅读 评论(0) 收藏 举报 性能布局viewStubinclude布局优化 目录(?)[-] Hierarchy View检测布局嵌套层次 显示GPU过度绘制 懒加载布局 ViewStub Android Lint 工具 怎样才能写出优秀的Android App,是

Android 性能优化 四 布局优化merge标签的使用

小白:之前分享了ViewStub标签的使用,Android还有其他优化布局的方式吗? 小黑:<merge />标签用于减少View树的层次来优化Android的布局.先来用个例子演示一下: 首先主需要一个配置文件activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andr

Android性能优化之一 布局优化

本文为Android性能优化--布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不必要的嵌套和View节点.减少不必要的infalte及其他Layout方面可调优点,顺带提及布局调优相关工具(hierarchy viewer和lint). 一.布局复杂度的优化 关于布局的优化,主要分两个大方向 实现相同界面效果并且层级结构相同时,选用何种Layout最好 在Android中单独的布局性能: FrameLayout>LinearLayout>Relat

Android Studido下的应用性能优化总结--布局优化

前言:一个应用的成功=产品设计*性能 ,再此我们不讨论一个应用的设计,那交给我们可爱又可恨的产品经理和UI设计师来决定!所以这里分步骤讨论如何提升一个应用的性能,这里先探讨布局优化问题. 布局优化 避免过度回执(Overdraw),由于过度绘制会浪费很多的CPU,GPU资源, 检查方法: 通过打开开发者选项–>GPU模式呈现分析–>在屏幕上显示为条形图.然后就会看到如下图的情况,最好用真机,模拟器回执有问题.  你可以观察一下绘制的条形图 tips:每一条柱状线都包含三部分,蓝色代表测量回执D

Android性能优化之布局优化篇

怎样才能写出优秀的Android App,是每一个程序员追求的目标.那么怎么才能写出一个优秀的App呢?相信很多初学者也会有这种迷茫.一句话来回答这个问题:细节很重要.今天我们就从最基础的XML布局来谈谈怎么提高Android性能问题吧! 也许你经常会遇到比较复杂的布局,这种情况下,最简单的方法就是多层嵌套实现效果,但是最简单的方法是否是最优的方法呢? 这里需要打一个大大的问号?????经验告诉我们,往往简单的方法,得到的结果不是最优解,那么我们通过一个例子来研究一下怎么去优化我们的XML布局吧

【Android 开发技巧】布局优化利器&lt;include/&gt;和ViewStub

『原创作品,转载请注明出处. --- 孙国威』 [文章原始地址 http://blog.csdn.net/manoel/article/details/39036507] 当创建复杂的布局的时候,有时候会发现添加了很多的ViewGroup和View.随之而来的问题是View树的层次越来越深,应用也变的越来越慢,因为UI渲染是非常耗时的. 这时候就应该进行布局优化了.这里介绍两种方式,分别为<include>标签和ViewStub类. <include/> 使用<include

性能优化之布局优化

1.抽象布局标签 (1) <include>标签include标签常用于将布局中的公共部分提取出来供其他layout共用,以实现布局模块化,这在布局编写方便提供了大大的便利.下面以在一个布局main.xml中用include引入另一个布局foot.xml为例.main.mxl代码如下: Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="utf-8"?> &l

(转载)性能优化之布局优化

来源:http://www.trinea.cn/android/layout-performance/ 本文为Android性能优化的第二篇——布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不必要的嵌套和View节点.减少不必要的infalte及其他Layout方面可调优点,顺带提及布局调优相关工具(hierarchy viewer和lint). 性能优化专题已完成五部分: 性能优化总纲——性能问题及性能调优方式性能优化第三篇——Java(Andro