New UI-<merge>标签减少视图层级,让布局更高效

New UI-<merge>标签减少视图层级,让布局更高效

 ——转载请注明出处:coder-pig,欢迎转载,请勿用于商业用途!

小猪Android开发交流群已建立,欢迎大家加入,无论是新手,菜鸟,大神都可以,小猪一个人的

力量毕竟是有限的,写出来的东西肯定会有很多纰漏不足,欢迎大家指出,集思广益,让小猪的博文

更加的详尽,帮到更多的人,O(∩_∩)O谢谢!

小猪Android开发交流群:小猪Android开发交流群群号:421858269

新Android UI实例大全目录:http://blog.csdn.net/coder_pig/article/details/42145907

本节引言:

前面我们已经学了布局优化的两个小技巧:

①使用include简化布局,解决布局复用的;②ViewStub延时加载,加快页面加载速度

那么今天再给大家介绍一个标签<merge>,"merge"直译"合并,混合",难道是合并布局?

呵呵,没错,你猜对了,是合并布局,不过有点遗憾的是,他合并的布局只能是:FrameLayout(帧布局)

只能合并一种布局,也没想象中那么种,仅仅减少关于FrameLayout的冗余层次,从而达到优化UI

的目的,事实如此,也不必多解释什么,不过每一样都系都有自己存在的意义,可能现在界面比较简单

的时候并不能体现他的价值,以后就知道了...而<merge>通常是

搭配着<include>标签来使用的,嗯呢,废话不多说,开始本节内容吧!

本节正文:

1.一个简单的例子引入<merge>

一个简单的FrameLayout的布局中:有一个普通的TextView:

布局文件如下:

<FrameLayout 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"
    tools:context="com.jay.example.test.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="呵呵"
        android:textSize="20sp" />

</FrameLayout>

那么,现在你来猜猜他的布局层次是怎么样的?

直接:LinearLayout -> FrameLayout  -> TextView 么?

带着疑惑,我们打开之前教过大家的布局层次查看工具:Hierarchy Viewer

如图,竟然出现了两个FrameLayout,第一反应,这没必要吧,把第二个FrameLayout搞掉!

恩,先不急,听我娓娓道来,从图中我们可以了解到这样一个信息,布局的结构基础都是:

PhoneWindowsDecorView -> LinearLayout  ->FrameLayout

接下来加载的布局资源都跟在这个FrameLayout后面就比如上面的布局

或许你还不信,我们在FrameLayout里添加上一个LinearLayout和一个TextView:

好了,上面这个图就验证了我们的说法,那么我们怎么来消除(优化)这个多余的FrameLayout呢?

就要用到今天要介绍的这个<merge>标签了!

2)merge标签怎么用:

答:超简单,直接把布局文件的外层的FrameLayout改成merge即可:

看下布局文件:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="呵呵"
        android:textSize="20sp" />

</merge>

没错,就是这么简单,从上面我们就可以看出,merge的作用是:

!!代替一层FrameLayout,如果是其他布局的话,他就没作用了哦!

除了上面这种应用情况外,我们更多的时候是跟这个include组合使用的

3)include结合merge:

这里找了网上的一个经典例子给大家体会下:

先看下层次图:

接下来就贴代码咯

编写流程:

①创建按钮布局文件okcalcelbar_button.xml

②创建okcancelbar.xml的文件,通过include引入两个上面的按钮

③values目录下面创建自定义属性的文件attrs.xml

④创建OkCancelBar类继承LinearLayout

⑤创建主布局文件

详细代码:

okcalcelbar_button.xml

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

okcancelbar.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <include
        android:id="@+id/okcancelbar_ok"
        layout="@layout/okcalcelbar_button" />

    <include
        android:id="@+id/okcancelbar_cancel"
        layout="@layout/okcalcelbar_button" />

</merge>

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="OkCancelBar">
        <attr name="okLabel" format="string"/>
       <attr name="cancelLabel" format="string"/>
    </declare-styleable>
</resources>

OkCancelBar.java:

package com.xzw.merge;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.widget.Button;
import android.widget.LinearLayout;

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是一个数组容器
		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();
	}

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>

<merge
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:okCancelBar="http://schemas.android.com/apk/res/com.xzw.merge">

	<ImageView
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent" 

		android:scaleType="center"
	    android:src="@drawable/golden_gate" />

	<com.xzw.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>

代码难点分析:

①attrs.xml文件:

上面自定义属性文件中OkCancelBar就是定义在<declare-styleable name="OkCancelBar">

</declare-styleable> 里的名字,获取里面属性用 名字_ 属性 连接起来就可以.

TypedArray 通常最后调用 .recycle() 方法,为了保持以后使用该属性一致性!

②activity_main.xml文件

xmlns:okCancelBar:是我们自定义属性的命名空间前缀。

也就是下面     okCancelBar:okLabel="Save"      okCancelBar:cancelLabel="Don‘t save"

用到的 "http://schemas.android.com/apk/res/com.xzw.merge" 

其中com.xzw.merge 是类文件所在包名。使用自定义属性必须加上该命名空间。

ps:简单点说就是attrs.xml自定义两个属性,以及设置属性的类型,然后在使用该自定义属性的布局中,

需要添加

xmlns:"declare-styleable里的name值"="http://schemas.android.com/apk/res/自定义类文件所在包名"

然后可以通过:

TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.OkCancelBar, 0, 0);

获取里面两个属性的值!接下来的就自己想咯!

4)merge的一些注意事项:

①merge标签只能作为xml文件的根节点,就是最外层的那个

②merge只能合并FrameLayout哦,如果根节点为LinearLayout或者其他,再使用<merge>标签

就会报错哦!

③使用LayoutInflater的inflate方法加载<merge>标签的布局文件时,需要为他指定一个父容器控件,

并且设置attachToRoot属性为true!!!

最后说两句:

关于merge合并布局就写到这里,如果后续有什么新的发现,会补上...

本节demo下载:MergeTest

参考资料:

http://bbs.51cto.com/thread-969619-1.html

时间: 2024-10-10 07:48:28

New UI-<merge>标签减少视图层级,让布局更高效的相关文章

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布局中使用include和merge标签

内容转自:http://fengweipeng1208.blog.163.com/blog/static/21277318020138229754135/ 在我们开发android布局时,经常会有很多的布局是相同的,这个时候我们可以通过<include/>和<merge/>标签实现将复杂的布局包含在需要的布局中,减少重复代码的编写. 1. 创建一个可以重复使用的布局: 如下代码描述在应用中每个acitivity都出现的顶栏titlebar.xml 1 <FrameLayout

安卓使用merge标签和include优化UI布局

转自:http://blog.sina.com.cn/s/blog_62f987620100sf13.html 单独将<merge />标签做个介绍,是因为它在优化UI结构时起到很重要的作用.目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构.核心功能就是减少冗余的层次从而达到优化UI的目的! 将通过一个例子来了解这个标签实际所产生的作用,这样可以更直观的了解<merge/>的用法. 建立一个简单的Layout,其中包含两个Views元素:ImageV

Android应用开发之性能优化3:merge标签

之前在开发中我也没有用过merge这个标签,后来经同事给我讲了下,我就尝试着用了merge标签,发现这个标签对应用布局优化确实有很大的帮助.今天就简单讲下这个标签的用法.说到<merge />标签对应用的优化主要是优化UI结构:通过删减多余或者额外的层级,从而优化整个Android 应用中Layout布局的结构. 将通过一个例子来了解这个标签实际所产生的作用,这样可以更直观的了解<merge/>的用法.不过在用的时候我们要注意: 1,<merge />只可以作为 lay

Android &lt;merge&gt;标签详解

单独将<merge/>标签做个介绍,是因为它在优化UI结构时起到很重要的作用.目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构.核心功能就是减少冗余的层次从而达到优化UI的目的! 将通过一个例子来了解这个标签实际所产生的作用,这样可以更直观的了解<merge/>的用法. 建立一个简单的Layout,其中包含两个Views元素:ImageView和TextView 默认状态下我们将这两个元素放在FrameLayout中.其效果是在主视图中全屏显示一张图

android 使用&lt;merge&gt;标签

<merge /> 标签在你嵌套 Layout 时取消了 UI 层级中冗余的 ViewGroup .比如,如果你有一个 Layout 是一个竖直方向的 LinearLayout,其中包含两个连续的 View 可以在别的 Layout 中重用,那么你会做一个 LinearLayout 来包含这两个 View ,以便重用.不过,当使用一个 LinearLayout 作为另一个 LinearLayout 的根节点时,这种嵌套 LinearLayout 的方式除了减慢你的 UI 性能外没有任何意义.

布局技巧2:合并布局(merge标签)

我们已经有文章向你描述如何使用<include />标签来重用和共享你的布局代码.这篇文章将向你阐述<merge />标签的使用以及如何与<include />标签互补使用. <merge />标签用于减少View树的层次来优化Android的布局.通过看一个例子,你就能很容易的理解这个标签能解决的问题.下面的XML布局显示一个图片,并且有一个标题位于其上方.这个结构相当的简单:FrameLayout里放置了一个ImageView,其上放置了一个TextVi

Android include和merge标签的使用

在Android布局文件中,某些时候使用include标签会很多的好处1,对于稍微有点复杂的布局界面,将所有布局代码都写在一个xml文件中,界面会显得很冗余,可读性很差,这时可以分开使用include标签来处理2,当Activity需要用到同样的布局效果,也可以使用include标签处理,而不用把一样的布局代码重复拷贝几遍,不用以后修改起来每个地方都要修改,提高了代码的重用性我们先用include标签实现下面的效果 activity_main.xml <RelativeLayout xmlns:

Android仿微信UI布局视图(圆角布局的实现)

圆角按钮,或布局可以在xml文件中实现,但也可以使用图片直接达到所需的效果,以前版本的微信就使用了这种方法. 实现效果图:    不得不说,这种做法还是比较方便的. 源代码: MainActivity(没写任何代码,效果全在布局文件中实现): package com.android_settings; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity