[Android]繼承式UI界面佈局設計

通常而言,Android界面佈局使用聚合的方式比較多,這種方式要求首先構建一批可以複用的組件,而後在Activity的佈局文件中進行聚合。儘管這種方式可以完成組件的複用,但若是這些組件在不一樣Activity中的佈局有不少相同點的時候,也仍是會帶來很大程度的冗餘(代碼)。本文介紹一種比聚合更加有效的界面佈局方式——繼承式佈局。java

對於類的繼承和對象的聚合之間有哪些相同點和不一樣點,分別適用於哪一種場景,相信你們已經深有體會。在此就很少講了。其實類比過來,Android的界面佈局也是如此。假設咱們須要實現以下的三種佈局:android

[Android]繼承式UI界面佈局設計 - lvan - lvan GoGo 的世界[Android]繼承式UI界面佈局設計 - lvan - lvan GoGo 的世界[Android]繼承式UI界面佈局設計 - lvan - lvan GoGo 的世界

每個佈局都是在前一個佈局的基礎上增長本身的元素。這種形式多麼像類的繼承呀!下面列出實現文件:網絡

page_three_parts.xmlapp

<?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>
ide

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.xmlui

<?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>
this

繼承式佈局在第一個節點處包含父佈局文件,而後實現子佈局。繼承式佈局要求父佈局和子佈局的根佈局大小必須一致。至於爲何這麼要求,很簡單,想想類繼承的特色——子類必須實現父類的全部內容,或者說子類必須可以代替父類。這樣的繼承方式與咱們在C++、C#、Java中實現的繼承很不同,而與GObject、Lua等實現繼承的方式很類似。spa

這種佈局方式可以比聚合實現更簡單的設計,並且可以更大程度的完成代碼和佈局的解耦合。這裏指的是有不少人會在聚合式佈局中留出擴展點,而後在程序運行的時候將內容填充到保留點。這種方式有一個很大的問題,就是隻有當程序運行起來以後才能看到頁面的完整信息。繼承式佈局就不存在這樣的問題。並且,這種繼承關係也徹底能夠映射到代碼類的繼承。下面是代碼中關於佈局的繼承關係:

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);
}

}

繼承式佈局其實是經過佈局的層層疊加實現的,但這種疊加是邏輯上的,而不是渲染層次的。因此在實際運行中不會帶來太大的性能問題。下面這張圖應該可以將繼承式佈局形象的展現出來:

[Android]繼承式UI界面佈局設計 - lvan - lvan GoGo 的世界

相關文章
相關標籤/搜索