关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android布局优化利器include和ViewStub

    Android布局优化利器include和ViewStub

    2014-09-13 00:00:00 出处:Napolean的技术博客
    分享

    当创建复杂的布局的时候,有时候会发现添加了很多的viewGroup和View。随之而来的问题是View树的层次越来越深,应用也变的越来越慢,因为UI渲染是非常耗时的。

    这时候就应该进行布局优化了。这里介绍两种方式,分别为<include>标签和ViewStub类。

    <include/>

    使用<include/>是为了避免代码的重复。设想一种情况,我们需要为app中的每个视图都添加一个footer,这个footer是一个显示app名字的TextView。通常多个Activity对应多个XML布局文件,难道要把这个TextView复制到每个XML中吗?假如TextView需要做修改,那么每个XML布局文件都要进行修改,那简直是噩梦。

    面向对象编程的其中一个思想就是代码的复用,那么怎么进行布局的复用呢?这时,<include/>就起作用了。

    假如学过C语言,那么对#include应该不陌生,它是一个预编译指令,在程序编译成二进制文件之前,会把#include的内容拷贝到#include的位置。

    Android中的<include/>也可以这么理解,就是把某些通用的xml代码拷贝到<include/>所在的地方。以一个Activity为例。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center_horizontal"
            android:text="@string/hello" />
    
        <include layout="@layout/footer_with_layout_properties"/>
    
    </RelativeLayout>

    footer_with_layout_properties.xml中就是一个简单的TextView,代码如下:

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="30dp"
        android:gravity="center_horizontal"
        android:text="@string/footer_text" />

    上述的代码中,我们使用了<include/>标签,达到了代码复用的目的。

    但是,仍然存在一些疑惑。

    footer_with_layout_properties.xml中使用了android:layout_alignParentBottom属性,这个属性之所以可行,是因为外层布局是RelativeLayout。

    那么,假如外层布局换做LinearLayout又会怎样呢?答案显而易见,这肯定是行不通的。那么怎么办呢?我们可以把具体的属性写在<include/>标签里面,看下面的代码。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center_horizontal"
            android:text="@string/hello"/>
        <include
            layout="@layout/footer"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="30dp"/>
    </RelativeLayout>

    我们直接在<include/>标签里面使用了android:layout_*属性。

    注意:假如想要在<include/>标签中覆盖被包含布局所指定的任何android:layout_*属性,必须在<include/>标签中同时指定layout_width和layout_height属性,这可能是一个Android系统的一个bug吧。

    ViewStub

    在开发过程中,难免会遇到各种交互问题,例如显示或隐藏某个视图。假如想要一个视图只在需要的时候显示,可以尝试使用ViewStub这个类。

    先看一下ViewStub的官方介绍:

    “ViewStub是一个不可视并且大小为0的视图,可以延迟到运行时填充布局资源。当ViewStub设置为Visible或调用inflate()之后,就会填充布局资源,ViewStub便会被填充的视图替代”。

    现在已经清楚ViewStub能干什么了,那么看一个例子。一个布局中,存在一个MapView,只有需要它的时候,才让它显示出来。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    
        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:onClick="onShowMap"
            android:text="@string/show_map" />
    
        <ViewStub
            android:id="@+id/map_stub"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:inflatedId="@+id/map_view"
            android:layout="@layout/map" />
    
    </RelativeLayout>

    map.xml文件中包含一个MapView,只有在必要的时候,才会让它显示出来。

    <com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="my_api_key"
        android:clickable="true" />

    另外,inflatedId是ViewStub被设置成Visible或调用inflate()方法后返回的id,这个id就是被填充的View的id。在这个例子中,就是MapView的id。

    接下来看看ViewStub是怎么使用的。

    public class MainActivity extends MapActivity {
    
      private View mViewStub;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mViewStub = findViewById(R.id.map_stub);
      }
    
      public void onShowMap(View v) {
        mViewStub.setVisibility(View.VISIBLE);
      }
    
      @Override
      protected boolean isRouteDisplayed() {
        return false;
      }
    }

    题外话

    有的同学肯定会问,使用ViewStub和单纯地把View设置为View.GONE或View.VISIBLE有什么区别呢?不都是显示和隐藏吗,使用ViewStub反而更麻烦了。

    确实是有区别的,会涉及到View树的渲染,内存消耗等。

    至于有什么具体的差别,就请大家自己去Google吧。俗话说,自己动手,丰衣足食嘛!

    参考资料

    http://code.google.com/p/android/issues/detail id=2863

    http://android-developers.blogspot.com.ar/2009/03/android-layout-tricks-3-optimize-with.html

    http://developer.android.com/reference/android/view/ViewStub.html

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。