Android移动应用界面的模板化设计

Android没有像苹果开发那样功能强大的界面开发工具,本身 ADT插件提供的界面编辑能力有限,没办法刻画所有的界面情况;Android的界面xml代码可以进行人工修改,而Iphone的全部在图形界面上拖动 完成,可没提供任何方式的代码级修改。Android的UI设计开发过程非常繁琐,容易出错,需要很长时间调节界面细节,开发过Android应用的人肯 定深有同感。用几年前的网页设计来打个比方,开发Iphone的软件界面就好比是用Frontpage弄点控件拖成一张页面,而开发Android更接近 于闭着眼睛在Notepad里一行行的写html标签。为了使开发Android应用更加简便快捷,减少代码冗余,增强软件质量,在咨询行情的开发上我们 大量使用了模板化的页面。
思路很简单:将软件里用到的大量重复的页面布局抽象出来,编写成一个抽象的Activity类,然后在实现具体页面时继承它,并且在主内容空白区填入需要的内容。
例如在最近开发的一款资讯类应用中,每张页面上面都有一个顶栏,上面有两个按钮,按钮中间是一行标题文字。按钮上的文字及点击后的功能在每个页面中可能会都不相同。如下图所示的。


面对这样一个页面的需求,我们可以设计出一个基本的页面模板AbstractAc1,代码如下所示。

  1. /**
  2. * 通用页面模板1:含上栏,包括左右两个按钮,一个title文字区
  3. * @author zhe.yangz
  4. */
  5. public class AbstractAc1 extends BaseActivity {
  6.     @Override
  7.     public void onCreate(Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         setContentView(R.layout.abac_1);
  10.     }
  11.     /**
  12.      * 设置主内容区域的layoutRes
  13.      * @param layoutResId
  14.      */
  15.     public void alabSetContentView(int layoutResId) {
  16.         LinearLayout llContent = (LinearLayout) findViewById(R.id.llContent1);
  17.         LayoutInflater inflater = (LayoutInflater) getSystemService(
  18.                 Context.LAYOUT_INFLATER_SERVICE);
  19.         View v = inflater.inflate(layoutResId, null);
  20.         llContent.addView(v);
  21.     }
  22.     /**
  23.      * 隐藏左侧按钮
  24.      */
  25.     public void alabHideButtonLeft(boolean bSetHide) {
  26.         Button bt = alabGetButtonLeft();
  27.         if (null != bt) {
  28.             if (bSetHide) bt.setVisibility(View.INVISIBLE);
  29.             else bt.setVisibility(View.VISIBLE);
  30.         }
  31.     }
  32.     /**
  33.      * 隐藏右侧按钮
  34.      */
  35.     public void alabHideButtonRight(boolean bSetHide) {
  36.         Button bt = alabGetButtonRight();
  37.         if (null != bt) {
  38.             if (bSetHide) bt.setVisibility(View.INVISIBLE);
  39.             else bt.setVisibility(View.VISIBLE);
  40.         }
  41.     }
  42.     /**
  43.      * 得到模板上导航栏的左侧按钮,一般为[返回]
  44.      * @return 成功则返回Button对象,失败则返回null。
  45.      */
  46.     public Button alabGetButtonLeft() {
  47.         return (Button) findViewById(R.id.btBack1);
  48.     }
  49.     /**
  50.      * 得到模板上导航栏的右侧按钮,一般为[刷新]
  51.      * @return 成功则返回Button对象,失败则返回null。
  52.      */
  53.     public Button alabGetButtonRight() {
  54.         return (Button) findViewById(R.id.btRefresh1);
  55.     }
  56.     /**
  57.      * 设置模板上导航栏中间的标题文字
  58.      * @param titleText
  59.      * @return 修改成功返回true,失败返回false
  60.      */
  61.     public boolean alabSetBarTitleText(String titleText) {
  62.         TextView tv = (TextView) findViewById(R.id.txBarTitle1);
  63.         if (null != tv) {
  64.             tv.setText(titleText);
  65.             return true;
  66.         }
  67.         return false;
  68.     }
  69. }

我们创建了一张模板页面,然后在应用中的实际页面继承于它。这样,每张继承的页面都可以拥有类似的顶栏布局,并且代码简洁。下面就是继承的例子。

  1. /**
  2. * 样例页面
  3. * @author zhe.yangz
  4. */
  5. public class HomeActivity extends AbstractAc1 {
  6.     @Override
  7.     public void onCreate(Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         alabSetContentView(R.layout.ac_home);
  10.         setTopBarAndAction();
  11.     }
  12.     private void setTopBarAndAction() {
  13.         alabSetBarTitleText("TEST HOME"); // 设置Title标题
  14.         alabGetButtonLeft().setText("LeftBt"); // 设置左按钮上的文字
  15.         alabGetButtonRight().setText("RightBt"); // 设置右按钮上的文字
  16.         alabGetButtonRight().setOnClickListener(new OnClickListener() {
  17.             @Override
  18.             public void onClick(View v) {
  19.                 // 按钮执行事件
  20.                 // ...
  21.             }
  22.         });
  23.     }
  24. }

就完成了一张具有如下顶栏效果的页面,页面的背景、按钮配色等效果在AbstractAc1中定义。


alabSetContentView()是在AbstractAc1中定义的方法,在衍生类中调用该方法,传入一个界面定义xml,方法中实现了使用 LayoutInflater生成view,使得这个页面中定义的主内容区的界面xml会和原来AbstractAc1的界面xml合并在一起,成为一个 完整的页面。有些情况下,左右按钮可以单独或一起隐藏,可以使用AbstractAc1中定义的alabHideButtonLeft和 alabHideButtonRight进行设置。
使用模板化方式开发界面,目前我们开发的Android应用中的Activity的层次结构大致如下。


这样模板化的页面探索的实践被用在我们目前Android应用开发中。大致估计一下,界面代码比原来减少40%,减少了冗余,也间接提高了软件质量和可维 护性,极大提升了业务需求变化带来的快速反应能力。接下去我们希望能够继续深入探索,找到更多的提升移动软件界面开发效率和质量的方法,也希望有好想法的 同学和我们深入交流,共同探讨,博采众长。

补充:
文中模板1中所用的布局定义文件abac_1.xml忘给出了,代码如下,

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.         android:orientation="vertical" android:layout_width="fill_parent"
  4.         android:layout_height="fill_parent" android:background="@color/section_bgcolor">
  5.         <!-- 顶栏 -->
  6.         <LinearLayout
  7.                 android:layout_width="fill_parent"
  8.                 android:layout_height="43dp"
  9.                 android:padding="5dp"
  10.                 android:background="@drawable/topbar_bg"
  11.                 android:orientation="horizontal"
  12.                 android:gravity="center" >
  13.                 <Button style="@style/AliBt" mce_style="@style/AliBt"
  14.                         android:id="@+id/btLeft"
  15.                         android:text="Left" />
  16.                 <Spinner android:id="@+id/sp_HY"
  17.                         android:visibility="invisible"
  18.                         android:layout_width="0dp"
  19.                         android:layout_height="0dp"/>
  20.                 <TextView style="@style/AliBarTitle" mce_style="@style/AliBarTitle"
  21.                         android:id="@+id/txBarTitle1"
  22.                         android:text="" />
  23.                 <Button style="@style/AliBt" mce_style="@style/AliBt"
  24.                         android:id="@+id/btRight"
  25.                         android:text="Right" />
  26.         </LinearLayout>
  27.         <!-- 主内容框架 -->
  28.         <LinearLayout
  29.                 android:id="@+id/llContent1"
  30.                 android:orientation="vertical"
  31.                 android:layout_width="fill_parent"
  32.                 android:layout_height="0dp"
  33.                 android:layout_weight="1">
  34.         </LinearLayout>
  35.        
  36. </LinearLayout>

 

posted @ 2013-08-14 09:31  brave-sailor  阅读(778)  评论(0编辑  收藏  举报