思路很简单:将软件里用到的大量重复的页面布局抽象出来,编写成一个抽象的Activity类,然后在实现具体页面时继承它,并且在主内容空白区填入需要的内容。
例如在最近开发的一款资讯类应用中,每张页面上面都有一个顶栏,上面有两个按钮,按钮中间是一行标题文字。按钮上的文字及点击后的功能在每个页面中可能会都不相同。如下图所示的。
面对这样一个页面的需求,我们可以设计出一个基本的页面模板AbstractAc1,代码如下所示。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="@color/section_bgcolor">
<!-- 顶栏 -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="43dp"
android:padding="5dp"
android:background="@drawable/topbar_bg"
android:orientation="horizontal"
android:gravity="center" >
<Button style="@style/AliBt" mce_style="@style/AliBt"
android:id="@+id/btLeft"
android:text="Left" />
<Spinner android:id="@+id/sp_HY"
android:visibility="invisible"
android:layout_width="0dp"
android:layout_height="0dp"/>
<TextView style="@style/AliBarTitle" mce_style="@style/AliBarTitle"
android:id="@+id/txBarTitle1"
android:text="" />
<Button style="@style/AliBt" mce_style="@style/AliBt"
android:id="@+id/btRight"
android:text="Right" />
</LinearLayout>
<!-- 主内容框架 -->
<LinearLayout
android:id="@+id/llContent1"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
</LinearLayout>
</LinearLayout>
* 通用页面模板1:含上栏,包括左右两个按钮,一个title文字区
* @author zhe.yangz
*/
public class AbstractAc1 extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.abac_1);
}
/**
* 设置主内容区域的layoutRes
* @param layoutResId
*/
public void alabSetContentView(int layoutResId) {
LinearLayout llContent = (LinearLayout) findViewById(R.id.llContent1);
LayoutInflater inflater = (LayoutInflater) getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(layoutResId, null);
llContent.addView(v);
}
/**
* 隐藏左侧按钮
*/
public void alabHideButtonLeft(boolean bSetHide) {
Button bt = alabGetButtonLeft();
if (null != bt) {
if (bSetHide) bt.setVisibility(View.INVISIBLE);
else bt.setVisibility(View.VISIBLE);
}
}
/**
* 隐藏右侧按钮
*/
public void alabHideButtonRight(boolean bSetHide) {
Button bt = alabGetButtonRight();
if (null != bt) {
if (bSetHide) bt.setVisibility(View.INVISIBLE);
else bt.setVisibility(View.VISIBLE);
}
}
/**
* 得到模板上导航栏的左侧按钮,一般为[返回]
* @return 成功则返回Button对象,失败则返回null。
*/
public Button alabGetButtonLeft() {
return (Button) findViewById(R.id.btBack1);
}
/**
* 得到模板上导航栏的右侧按钮,一般为[刷新]
* @return 成功则返回Button对象,失败则返回null。
*/
public Button alabGetButtonRight() {
return (Button) findViewById(R.id.btRefresh1);
}
/**
* 设置模板上导航栏中间的标题文字
* @param titleText
* @return 修改成功返回true,失败返回false
*/
public boolean alabSetBarTitleText(String titleText) {
TextView tv = (TextView) findViewById(R.id.txBarTitle1);
if (null != tv) {
tv.setText(titleText);
return true;
}
return false;
}
}
alabSetContentView()是在AbstractAc1中定义的方法,在衍生类中调用该方法,传入一个界面定义xml,方法中实现了使用LayoutInflater生成view,使得这个页面中定义的主内容区的界面xml会和原来AbstractAc1的界面xml合并在一起,成为一个完整的页面。有些情况下,左右按钮可以单独或一起隐藏,可以使用AbstractAc1中定义的alabHideButtonLeft和alabHideButtonRight进行设置。
使用模板化方式开发界面,目前我们开发的Android应用中的Activity的层次结构大致如下。
这样模板化的页面探索的实践被用在我们目前Android应用开发中。大致估计一下,界面代码比原来减少40%,减少了冗余,也间接提高了软件质量和可维护性,极大提升了业务需求变化带来的快速反应能力。