Android UI开发详解之模板控件的复用

jopen 11年前

Android的UI设计一直是Android程序员比较苦恼的一件事,本文主要讲解如何将一些模板类控件进行复用,从而简化UI的开发。

如图:

Android UI开发详解之模板控件的复用

我们很多程序的界面中,顶部的TopBar是不变的,所以,我们可以做一个公用的控件模板,每次使用时,只要设置相应的参数,就能生成这样一个TopBar。

模板控件实现方法:

package com.xys.multiplexedmodule;    import android.content.Context;  import android.content.res.TypedArray;  import android.graphics.Color;  import android.graphics.drawable.Drawable;  import android.text.TextUtils.TruncateAt;  import android.util.AttributeSet;  import android.view.Gravity;  import android.view.View;  import android.view.ViewGroup;  import android.widget.Button;  import android.widget.RelativeLayout;  import android.widget.TextView;    public class MultipleTopBar extends RelativeLayout{      private Button btn_left;   private Button btn_right;   private TextView tv_title;      private TopBarClickListener topBarClickListener;   private String str_title;      private RelativeLayout.LayoutParams leftButtonLayoutParams;   private RelativeLayout.LayoutParams rightButtonLayoutParams;   private RelativeLayout.LayoutParams tvTitleLayoutParams;      private static int leftBtnId=1;   private static int titleTvId=2;   private static int rightBtnId=3;      private Drawable leftBtnBackground;   private Drawable rightBtnBackground;      private String str_LeftBtn;   private String str_RightBtn;   private int leftBtnColor;   private int rightBtnColor;   private int titleTvColor;      private float titleTextSize;      public MultipleTopBar(Context context, AttributeSet attrs) {    super(context, attrs);    // TODO Auto-generated constructor stub    //从参数列表中获取参数    //TypedArray实例是个属性的容器,context.obtainStyledAttributes()方法返回得到。AttributeSet是节点的属性集合    //第二个参数为 为获取到值时的默认值    TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.TopBar);    this.str_title=ta.getString(R.styleable.TopBar_title);    this.leftBtnBackground=ta.getDrawable(R.styleable.TopBar_leftBackground);    this.rightBtnBackground=ta.getDrawable(R.styleable.TopBar_rightBackground);    this.str_LeftBtn=ta.getString(R.styleable.TopBar_leftText);    this.str_RightBtn=ta.getString(R.styleable.TopBar_rightText);    this.leftBtnColor=ta.getColor(R.styleable.TopBar_leftTextColor, 0);    this.rightBtnColor=ta.getColor(R.styleable.TopBar_rightTextColor, 0);    this.titleTextSize=ta.getDimension(R.styleable.TopBar_titleTextSize, 14);    this.titleTvColor=ta.getColor(R.styleable.TopBar_titleTextColor, 0);        ta.recycle();        btn_left=new Button(context);    btn_right=new Button(context);    tv_title=new TextView(context);        btn_left.setId(leftBtnId);    btn_right.setId(rightBtnId);    tv_title.setId(titleTvId);        //为组件配置布局参数    leftButtonLayoutParams=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);    rightButtonLayoutParams=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);    tvTitleLayoutParams=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);        leftButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,RelativeLayout.TRUE);    leftButtonLayoutParams.setMargins(12, 0, 0, 0);//左上右下    leftButtonLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);              rightButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,RelativeLayout.TRUE);    rightButtonLayoutParams.setMargins(0, 0, 12, 0);//左上右下    rightButtonLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);              tvTitleLayoutParams.setMargins(12, 0, 12, 0);//左上右下    tvTitleLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);    tvTitleLayoutParams.addRule(RelativeLayout.LEFT_OF, rightBtnId);    tvTitleLayoutParams.addRule(RelativeLayout.RIGHT_OF, leftBtnId);    //tvTitleLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);    tv_title.setGravity(Gravity.CENTER);    tv_title.setBackgroundColor(leftBtnColor);                    addView(btn_left, leftButtonLayoutParams);          addView(btn_right,rightButtonLayoutParams);          addView(tv_title,tvTitleLayoutParams);                    //btn_left.setBackgroundDrawable(leftBtnBackground);          btn_left.setText(str_LeftBtn);          btn_left.setTextColor(leftBtnColor);          //btn_right.setBackgroundDrawable(rightBtnBackground);          btn_right.setText(str_RightBtn);          btn_right.setTextColor(rightBtnColor);                    tv_title.setTextSize(22.0f);          tv_title.setTextColor(Color.BLUE);          tv_title.setEllipsize(TruncateAt.MIDDLE);          tv_title.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);          tv_title.setSingleLine(true);          tv_title.setText(str_title);          tv_title.setTextSize(titleTextSize);          tv_title.setTextColor(titleTvColor);                    btn_left.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {       // TODO Auto-generated method stub       if(topBarClickListener!=null){                          topBarClickListener.leftBtnClick();                  }      }          });                    btn_right.setOnClickListener(new OnClickListener() {                  @Override                  public void onClick(View v) {                          if(topBarClickListener!=null){                                  topBarClickListener.rightBtnClick();                          }                  }          });       }      /*    * 单击监听事件    */   public void setTopBarClickListener(TopBarClickListener topBarClickListener){    this.topBarClickListener=topBarClickListener;   }  }

 

监听接口:

package com.xys.multiplexedmodule;    public interface TopBarClickListener {     void leftBtnClick();   void rightBtnClick();  }

对我们自定义的模板控件,我们需要设定他的一些参数,在Values下新建attrs.xml:

<?xml version="1.0" encoding="utf-8"?>  <resources>  <!--declare-styleable:自定义属性的值  -->      <declare-styleable name="TopBar">          <attr name="title" format="string" />          <attr name="titleTextSize" format="dimension" />          <attr name="titleTextColor" format="color" />          <attr name="leftTextColor" format="color" />          <attr name="leftBackground" format="string" />          <attr name="leftText" format="string" />          <attr name="rightTextColor" format="color" />          <attr name="rightBackground" format="string" />          <attr name="rightText" format="string" />      </declare-styleable>    </resources>

现在我们就已经做好了一个模板,我们要如何使用他呢,很简单:

测试类:

package com.xys.multiplexedmodule;    import android.os.Bundle;  import android.app.Activity;  import android.view.Menu;  import android.widget.Toast;    public class TestActivity extends Activity {     private MultipleTopBar topBar;         @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          topBar=(MultipleTopBar)findViewById(R.id.topBar);          topBar.setTopBarClickListener(new TopBarClickListener() {          @Override     public void rightBtnClick() {      // TODO Auto-generated method stub      Toast.makeText(TestActivity.this, "你点击的是右边的按钮", Toast.LENGTH_LONG).show();     }          @Override     public void leftBtnClick() {      // TODO Auto-generated method stub      Toast.makeText(TestActivity.this, "你点击的是左边的按钮", Toast.LENGTH_LONG).show();     }    });      }          @Override      public boolean onCreateOptionsMenu(Menu menu) {          // Inflate the menu; this adds items to the action bar if it is present.          getMenuInflater().inflate(R.menu.main, menu);          return true;      }        }

引用模板的布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      xmlns:custom="http://schemas.android.com/apk/res/com.xys.multiplexedmodule"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:paddingBottom="@dimen/activity_vertical_margin"      android:paddingLeft="@dimen/activity_horizontal_margin"      android:paddingRight="@dimen/activity_horizontal_margin"      android:paddingTop="@dimen/activity_vertical_margin"      tools:context=".TestActivity" >   <!--一定要加入引用 xmlns:custom="http://schemas.android.com/apk/res/com.xys.multiplexedmodule"  -->      <LinearLayout          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_alignParentLeft="true"          android:layout_alignParentRight="true"          android:layout_alignParentTop="true"          android:orientation="vertical" >            <com.xys.multiplexedmodule.MultipleTopBar              android:id="@+id/topBar"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              custom:leftBackground="@drawable/ic_launcher"              custom:leftText="左侧"              custom:leftTextColor="#ff0000"              custom:rightBackground="@drawable/ic_launcher"              custom:rightText="右侧"              custom:rightTextColor="#ff0000"              custom:title="自定义标题"              custom:titleTextColor="#123412"              custom:titleTextSize="14.0sp" >          </com.xys.multiplexedmodule.MultipleTopBar>      </LinearLayout>    </RelativeLayout>

这样我们就可以使用我们新建的模板控件了,效果如下:

Android UI开发详解之模板控件的复用