`
h416756139
  • 浏览: 365792 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android布局技巧——合并布局

阅读更多

<merge />标签用于减少View树的层次来优化Android的布局。通过看一个例子,你就能很容易的理解这个标签能解决的问题。下面的XML布局显示一个图片,并且有一个标题位于其上方。这个结构相当的简单;FrameLayout里放置了一个ImageView,其上放置了一个TextView

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"
        android:padding="12dip"
        android:background="#AA000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate" />
</FrameLayout>

    布局渲染起来很漂亮,而且看不出有什么问题:

    当你使用HierarchyViewer工具来检查时,你会发现事情变得很有趣。如果你仔细查看View树,你将会注意到,我们在XML文件中定义的FrameLayout(蓝色高亮显示)是另一个FrameLayout唯一的子元素:

    既然我们的FrameLayout和它的父元素有着相同的尺寸(归功于fill_parent常量),并且也没有定义任何的background,额外的padding或者gravity,所以它完全是无用的。我们所做的,只是让UI变得更为复杂。怎样我们才能摆脱这个FrameLayout呢?毕竟,XML文档需要一个根标签且XML布局总是与相应的View实例想对应。

这时候,<merge />标签闪亮登场了。当LayoutInflater遇到这个标签时,它会跳过它,并将<merge />内的元素添加到<merge />的父元素里。迷惑了吗?让我们用<merge />来替换FrameLayout,并重写之前的XML布局:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"
        android:padding="12dip"
        android:background="#AA000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate" />
</merge>

    新的代码中,TextViewImageView都直接添加到上一层的FrameLayout里。虽然视觉上看起来一样,但View的层次更加简单了:

    很显然,在这个场合使用<merge />是因为ActivityContentView的父元素始终是FrameLayout。如果你的布局使用LinearLayout作为它的根标签(举例),那么你就不能使用这个技巧。<merge />在其它的一些场合也很有用的。例如,它与<include />标签结合起来就能表现得很完美。你还可以在创建一个自定义的组合View时使用<merge />。让我们看一个使用<merge />创建一个新View的例子——OkCancelBar,包含两个按钮,并可以设置按钮标签。下面的XML用于在一个图片上显示自定义的View

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">
    <ImageView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    <com.example.android.merge.OkCancelBar
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:paddingTop="8dip"
        android:gravity="center_horizontal"
        android:background="#AA000000"
        okCancelBar:okLabel="Save"
        okCancelBar:cancelLabel="Don't save" />
</merge>

新的布局效果如下图所示:

       OkCancelBar的代码很简单,因为这两个按钮在外部的XML文件中定义,通过LayoutInflate类导入。如下面的代码片段所示,R.layout.okcancelbarOkCancelBar为父元素:

public class OkCancelBar extends LinearLayout {
    public OkCancelBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        setWeightSum(1.0f);
        LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);
       
        String text = array.getString(R.styleable.OkCancelBar_okLabel);
        if (text == null) text = "Ok";
        ((Button) findViewById(R.id.okcancelbar_ok)).setText(text);
        text = array.getString(R.styleable.OkCancelBar_cancelLabel);
        if (text == null) text = "Cancel";
        ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text); 
        array.recycle();
    }
}

    两个按钮的定义如下面的XML所示。正如你所看到的,我们使用<merge />标签直接添加两个按钮到OkCancelBar。每个按钮都是从外部相同的XML布局文件包含进来的,便于维护;我们只是简单地重写它们的id

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_ok" />       
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_cancel" />
</merge>

    我们创建了一个灵活且易于维护的自定义View,它有着高效的View层次:

<merge />标签极其有用。然而它也有以下两个限制:

·         <merge />只能作为XML布局的根标签使用

·         Inflate<merge />开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoottrue(参看inflate(int, android.view.ViewGroup, Boolean)方法)。

转自:http://blog.sina.com.cn/s/blog_4d661a8c0100mnun.html

分享到:
评论

相关推荐

    Android开发——布局管理

    本文将深入探讨Android布局管理的基本概念、常用布局类型以及如何优化布局性能。 首先,Android提供了几种内置的布局类型,以满足不同设计需求: 1. **线性布局(LinearLayout)**:这是最基础的布局,支持水平或...

    安卓Android源码——android-times-square 安卓Android日历部件.zip

    "安卓Android源码——android-times-square 安卓Android日历部件.zip" 这个标题指的是一个开源项目,它包含了Android平台上的一个特定日历组件的源代码,名为“android-times-square”。这个组件是专门为Android应用...

    Android 2048——课设简单版

    【Android 2048——课设简单版】 在Android平台上开发一款2048游戏,是学习Android Studio和移动应用开发的一个经典实践项目。2048是一款基于数字的益智游戏,由Gabriele Cirulli在2014年推出,玩家通过滑动屏幕...

    安卓Android源码——Android Launcher 源码修改可编译.zip

    9. **版本控制与Git**:Android源码使用Git进行版本控制,开发者需要熟悉Git命令来管理代码分支、合并和回滚更改。 10. **单元测试与调试**:修改源码后,开发者需要编写和运行单元测试确保改动不会引入新的错误,...

    安卓Android源码——WordPress for Android.zip

    "安卓Android源码——WordPress for Android.zip" 这个标题明确指出,我们正在探讨的是关于Android操作系统的源代码,具体是针对WordPress的Android应用版本。WordPress是全球广泛使用的开源博客和内容管理系统,而...

    安卓Android源码——SportsBoards.zip

    《安卓Android源码——SportsBoards深度解析》 在安卓应用开发领域,深入理解源码是提升技术能力的重要途径。本篇文章将详细探讨SportsBoards项目中的关键知识点,旨在帮助开发者更好地理解和应用Android源码。 ...

    Android源码——旋转的地球源码.zip

    【标题】"Android源码——旋转的地球源码.zip" 提供的是一个Android应用程序的源代码,这个程序可能展示了一个动态的3D地球模型,它能够进行旋转,为用户呈现地球自转的效果。这个项目可能是为了教学目的,帮助...

    安卓Android源码——连连看.zip

    【标题】"安卓Android源码——连连看.zip" 提供的是一个基于Android平台开发的连连看游戏的源代码。连连看是一种广受欢迎的休闲益智游戏,玩家需要在限定时间内找到并消除一对对相同的图案。这个项目的源码对于我们...

    安卓Android源码——自动适应屏幕源码.zip

    Google提供的PercentSupportLibrary(现已合并到Android Support Library)或AndroidX的Layout Library允许使用百分比定义布局尺寸,让UI元素的比例在不同屏幕大小下保持一致。 6. **自定义视图组件**: 对于复杂...

    Android游戏——2048源码

    《Android游戏——2048源码》 2048是一款广受欢迎的数字合并游戏,它的源码对于安卓开发初学者来说,是一份非常有价值的参考资料。在这个项目中,开发者用简洁的代码实现了2048的核心功能,使得游戏逻辑清晰易懂,...

    安卓Android源码——仿美图秀秀拼图功能.zip

    本项目"安卓Android源码——仿美图秀秀拼图功能"就是一个很好的实例,它提供了一个类似美图秀秀的图片拼接功能。下面我们将详细探讨这个项目中的关键知识点。 1. **图片处理**: - 图片拼接:在Android中,我们...

    安卓Android源码——[安卓开源]生日管家 .zip

    "安卓Android源码——[安卓开源]生日管家 .zip" 这个标题揭示了我们讨论的主题是关于Android操作系统的源代码,更具体地说,是一个名为"生日管家"的应用程序的源代码。"安卓开源"指的是这个项目是基于开放源代码的...

    安卓Android源码——draw.rar

    "安卓Android源码——draw.rar"这个压缩包很可能是包含了与Android图形绘制相关的源代码。在这个话题中,我们将深入探讨Android系统的绘图机制,包括UI元素的渲染、硬件加速、Canvas、Paint以及View体系结构等核心...

    安卓Android源码——随手记安卓记账项目.zip

    《安卓Android源码——随手记安卓记账项目》 该项目主要涵盖了安卓Android平台上的一个开源记账应用的源代码分析,旨在帮助开发者了解如何在Android系统上开发一款实用的个人财务管理应用。随手记是一个功能丰富的...

    安卓Android源码——BMI健康计算器.zip

    在本项目中,我们关注的是一个基于安卓Android平台的源码实现——BMI(Body Mass Index,身体质量指数)健康计算器。这个应用可以帮助用户计算并理解他们的BMI值,从而评估其健康状况。以下是对这个源码项目的详细...

    安卓Android源码——益智游戏-推箱子源码.rar

    【安卓Android源码——益智游戏-推箱子源码】是一个专门为Android平台开发的经典益智游戏,基于Android SDK和Java编程语言实现。推箱子游戏源自日本,在全球范围内广受欢迎,其核心玩法是通过操作角色推动箱子到指定...

    Android源码——逐帧动画源码_new_70.zip

    这个"Android源码——逐帧动画源码_new_70.zip"文件很可能是为了展示如何在Android应用中实现逐帧动画。下面,我们将深入探讨Android平台上的逐帧动画原理及其代码实现。 一、逐帧动画的基本概念 逐帧动画是通过...

    安卓Android源码——阅读器.rar

    14. **优化**:阅读器可能包含性能优化技巧,如使用内存池、避免内存泄漏,以及使用懒加载和分页加载来减少资源消耗。 15. **版本控制**:源码库可能使用Git进行版本控制,展示如何通过分支、合并和提交来协同开发...

    经典项目——AndroidStudio版本.zip

    Android Studio支持Git版本控制系统,可以直接在IDE内完成代码提交、分支管理和合并操作,便于团队协作开发。 9. **插件扩展** Android Studio支持丰富的插件库,如 ButterKnife Zelezny、Android Annotation ...

    安卓Android源码——[安卓开源]仿QQ列表通讯录项目.rar

    【标题】"安卓Android源码——[安卓开源]仿QQ列表通讯录项目"是一个针对安卓平台的开源项目,旨在模仿QQ应用的通讯录功能。这个项目对于开发者来说,是一个很好的学习资源,它揭示了如何在Android平台上实现一个高效...

Global site tag (gtag.js) - Google Analytics