一般而言,Android界面布局使用聚合的方式比较多,这种方式要求首先构建一批能够复用的组件,然后在Activity的布局文件中进行聚合。尽管这种方式能够完成组件的复用,但如果这些组件在不同Activity中的布局有很多相同点的时候,也还是会带来很大程度的冗余(代码)。本文介绍一种比聚合更加有效的界面布局方式——继承式布局。

对于类的继承和对象的聚合之间有哪些相同点和不同点,分别适用于哪种场景,相信大家已经深有体会。在此就不多讲了。其实类比过来,Android的界面布局也是如此。假设我们需要实现如下的三种布局:

每一个布局都是在前一个布局的基础上增加自己的元素。这种形式多么像类的继承呀!下面列出实现文件:

page_three_parts.xml

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

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="96dp"
android:layout_alignParentTop="true"
android:background="@color/main_blue" >

<ImageView
android:id="@+id/image_logo"
android:layout_width="120dp"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="10dp"
android:gravity="center"
android:src="@drawable/logo" />
</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="96dp"
android:layout_alignParentBottom="true"
android:background="@color/main_blue" >
</RelativeLayout>

</RelativeLayout>

page_base_setting.xml

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

<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/page_three_parts" />


<Button
android:id="@+id/baseSettingButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="32dp"
android:text="page_base_setting.xml" />

</RelativeLayout>

page_net_settting.xml

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

<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/page_base_setting" />


<Button
android:id="@+id/netSettingButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="32dp"
android:text="page_net_settting.xml" />

</RelativeLayout>

继承式布局在第一个节点处包含父布局文件,然后实现子布局。继承式布局要求父布局和子布局的根布局大小必须一致。至于为什么这么要求,很简单,想一想类继承的特点——子类必须实现父类的所有内容,或者说子类必须能够代替父类。这样的继承方式与我们在C++、C#、Java中实现的继承很不一样,而与GObject、Lua等实现继承的方式很相似。

这种布局方式能够比聚合实现更简单的设计,而且能够更大程度的完成代码和布局的解耦合。这里指的是有很多人会在聚合式布局中留出扩展点,然后在程序运行的时候将内容填充到保留点。这种方式有一个很大的问题,就是只有当程序运行起来之后才能看到页面的完整信息。继承式布局就不存在这样的问题。而且,这种继承关系也完全可以映射到代码类的继承。下面是代码中关于布局的继承关系:

ThreePartsActivity.java

package com.testui;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

/**
* 该类和 page_three_parts.xml 布局文件对应
*/
public class ThreePartsActivity extends Activity {

/**
* 布局文件
*/
protected int layoutRes;

/**
* LOGO图片
*/
protected ImageView imageLogo;

protected ThreePartsActivity(int layoutRes) {
this.layoutRes = layoutRes;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 设置视图内容
setContentView(layoutRes);

imageLogo = (ImageView) findViewById(R.id.image_logo);
}

}

BaseSettingActivity.java

package com.testui;

import android.os.Bundle;
import android.widget.Button;

/**
* 该类和 page_base_setting.xml 布局文件对应
*/
public class BaseSettingActivity extends ThreePartsActivity {

/**
* 基本配置按钮
*/
Button baseSettingButton;

protected BaseSettingActivity(int layoutRes) {
super(layoutRes);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

baseSettingButton = (Button) findViewById(R.id.baseSettingButton);
}

}

NetSettingActivity.java

package com.testui;

import android.os.Bundle;
import android.widget.Button;

/**
* 该类和 page_net_settting.xml 布局文件对应
*/
public class NetSettingActivity extends BaseSettingActivity {

/**
* 网络设置按钮
*/
Button netSettingButton;

public NetSettingActivity() {
super(R.layout.page_net_settting);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

netSettingButton = (Button) findViewById(R.id.netSettingButton);
}

}

继承式布局实际上是通过布局的层层叠加实现的,但这种叠加是逻辑上的,而不是渲染层次的。所以在实际运行中不会带来太大的性能问题。下面这张图应该能够将继承式布局形象的展示出来:


更多相关文章

  1. Android简易计算器----布局_菜单_提示框 的运用
  2. Android(安卓)开发者 for Flutter (2)如何布局? XML layout 文件跑
  3. Android阻塞式确认Dialog-Loop实现方式
  4. 解决:eclipse导入android时工程下没有R文件的问题,以及style.xml文
  5. android 布局长度单位深入研究(2)
  6. android页面布局时定义控件ID时@id/XX和@+id/xx 有什么区别?
  7. Android(安卓)Studio官方文档之使用布局编辑器来设计UI界面
  8. android 上面一个listview下面一个button,让button一直处于listv
  9. mac 系统开发android,真机调试解决方式(无数的坑之后吐血总结)

随机推荐

  1. mySql 在Linux上安装
  2. 全面介绍 Linux 权限
  3. 详解linux中的backlog
  4. AEB功能安全(三):AEB场景分析及危害识别
  5. Linux基础:xargs命令
  6. 探索 Linux 上的 /run
  7. linux是什么操作系统以及Linux如何工作详
  8. 水塔无线自动供水实现方式
  9. Requests库快速学习
  10. GNOME Linux 桌面入门