1. 程式人生 > >自定義View之自定義標題欄

自定義View之自定義標題欄

現在,幾乎在每一個APP頂部都有一個標題欄,可能會用ActionBar,也可能自己寫一個xml來新增標題欄中的控制元件。在以往自己做專案時大多使用後者來寫一個標題欄,然後使用include包含在每一個頁面佈局中。今天,試下使用自定義屬性來自定義一個標題欄。

一般的標題欄都分為三個模組:左側、標題、右側,所以我們自定義的標題欄中允許使用者新增左側文字(或圖片)、標題、右側文字(或圖片),並且提供相應介面去呼叫點選事件。這裡的Demo只是一個小小的例子,後面可以根據所需修改這個標題欄。

詳細看下程式碼,功能還很少,也很簡單..

首先,繼承下RelativeLayout,然後在其中加入我們所需的控制元件:

/**
 * 自定義標題欄
 * @author AA
 * @Date 2015-01-19
 */
public class CustomTitleBar extends RelativeLayout {

    /** 文字 */
    private String mLeftText, mTitleText, mRightText;
    /** 文字大小 */
    private float mAmboTextSize, mTitleTextSize;
    /** 文字顏色 */
    private int mTextColor;
    /** 圖片 */
    private int mLeftImage, mRightImage;
    /** 是否可見 */
    private boolean mLeftVisible, mRightVisible;

    /** 左邊、標題、右邊 */
    private TextView mLeftTextView, mTitleTextView, mRightTextView;
    private ImageView mLeftImageView, mRightImageView;
    /** 標題欄檢視引數 */
    private LayoutParams mLeftParams, mTitleParams, mRightParams;
    /** 自定義點選監聽器 */
    private TitleBarClickListener mTitleBarClickListener;


    public CustomTitleBar(Context context) {
        this(context, null);
    }

    public CustomTitleBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomTitleBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        //獲得自定義屬性值
        getTypedArray(context, attrs);

        //建立LayoutParams,並且設定對齊方式
        mLeftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        mLeftParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);

        mTitleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);

        mRightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        mRightParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);

        //左邊文字
        if(StringUtils.isNotEmpty(mLeftText) && mLeftVisible) {
            mLeftTextView = new TextView(context);
            mLeftTextView.setText(mLeftText);
            mLeftTextView.setTextSize(mAmboTextSize);
            mLeftTextView.setTextColor(mTextColor);
            addView(mLeftTextView, mLeftParams);
            mLeftTextView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(mTitleBarClickListener != null) {
                        //呼叫介面中方法
                        mTitleBarClickListener.onLeftClickListener();
                    }
                }
            });
        }
        //右邊文字
        if(StringUtils.isNotEmpty(mRightText) && mRightVisible){
            mRightTextView = new TextView(context);
            mRightTextView.setText(mRightText);
            mRightTextView.setTextSize(mAmboTextSize);
            mRightTextView.setTextColor(mTextColor);
            addView(mRightTextView, mRightParams);
            mRightTextView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(mTitleBarClickListener != null) {
                        mTitleBarClickListener.onRightClickListener();
                    }
                }
            });
        }
        //標題文字
        if(StringUtils.isNotEmpty(mTitleText)) {
            mTitleTextView = new TextView(context);
            mTitleTextView.setText(mTitleText);
            mTitleTextView.setTextSize(mTitleTextSize);
            mTitleTextView.setGravity(Gravity.CENTER);
            mTitleTextView.setTextColor(mTextColor);
            addView(mTitleTextView, mTitleParams);
        }
        //左邊圖片按鈕
        if(mLeftImage > 0 && mLeftVisible) {
            mLeftImageView = new ImageView(context);
            mLeftImageView.setImageResource(mLeftImage);
            addView(mLeftImageView, mLeftParams);
            mLeftImageView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(mTitleBarClickListener != null) {
                        mTitleBarClickListener.onLeftClickListener();
                    }
                }
            });
        }
        //右邊圖片按鈕
        if(mRightImage > 0 && mRightVisible) {
            mRightImageView = new ImageView(context);
            mRightImageView.setImageResource(mRightImage);
            addView(mRightImageView, mRightParams);
            mRightImageView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(mTitleBarClickListener != null) {
                        mTitleBarClickListener.onRightClickListener();
                    }
                }
            });
        }
    }

    /**
     * 獲得自定義屬性值
     * @param context
     * @param attrs
     */
    private void getTypedArray(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar);
        int count = ta.getIndexCount();
        for(int i=0; i<count; i++) {
            int attr = ta.getIndex(i);
            switch (attr) {
                case R.styleable.CustomTitleBar_leftText:
                    mLeftText = ta.getString(attr);
                    break;

                case R.styleable.CustomTitleBar_titleText:
                    mTitleText = ta.getString(attr);
                    break;

                case R.styleable.CustomTitleBar_rightText:
                    mRightText = ta.getString(attr);
                    break;

                case R.styleable.CustomTitleBar_amboTextSize:
                    mAmboTextSize = DisplayUtils.px2sp(context, ta.getDimensionPixelSize(attr, 12));
                    break;

                case R.styleable.CustomTitleBar_titleTextSize:
                    mTitleTextSize = DisplayUtils.px2sp(context, ta.getDimensionPixelSize(attr, 16));
                    break;

                case R.styleable.CustomTitleBar_textColor:
                    mTextColor = ta.getColor(attr, Color.BLACK);
                    break;

                case R.styleable.CustomTitleBar_leftVisible:
                    mLeftVisible = ta.getBoolean(attr, false);
                    break;

                case R.styleable.CustomTitleBar_rightVisible:
                    mRightVisible = ta.getBoolean(attr, false);
                    break;

                case R.styleable.CustomTitleBar_leftImage:
                    mLeftImage = ta.getResourceId(attr, 0);
                    break;

                case R.styleable.CustomTitleBar_rightImage:
                    mRightImage = ta.getResourceId(attr, 0);
                    break;
            }
        }
        ta.recycle();
    }

    /**
     * 設定點選監聽事件
     * @param listener
     */
    public void setOnTitleBarClickListener(TitleBarClickListener listener) {
        this.mTitleBarClickListener = listener;
    }

    /**
     * 設定左側文字是否可見
     * @param visible
     */
    public void setLeftTextVisible(boolean visible) {
        this.mLeftTextView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    /**
     * 設定右側文字是否可見
     * @param visible
     */
    public void setRightTextVisible(boolean visible) {
        this.mRightTextView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    /**
     * 設定左側圖片是否可見
     * @param visible
     */
    public void setLeftImageVisible(boolean visible) {
        this.mLeftImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    /**
     * 設定右側圖片是否可見
     * @param visible
     */
    public void setRightImageVisible(boolean visible) {
        this.mRightImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    /**
     * 設定左側文字
     * @param text
     */
    public void setLeftText(String text) {
        this.mLeftTextView.setText(text);
    }

    /**
     * 設定標題文字
     * @param text
     */
    public void setTitleText(String text) {
        this.mTitleTextView.setText(text);
    }

    /**
     * 設定右側文字
     * @param text
     */
    public void setRightText(String text) {
        this.mRightTextView.setText(text);
    }

    /**
     * 設定左側文字大小
     * @param textSize
     */
    public void setLeftTextSize(float textSize) {
        this.mLeftTextView.setTextSize(textSize);
    }

    /**
     * 設定標題文字大小
     * @param textSize
     */
    public void setTitleTextSize(float textSize) {
        this.mTitleTextView.setTextSize(textSize);
    }

    /**
     * 設定右側文字大小
     * @param textSize
     */
    public void setRightTextSize(float textSize) {
        this.mRightTextView.setTextSize(textSize);
    }

    /**
     * 設定左側文字顏色
     * @param color
     */
    public void setLeftTextColor(int color) {
        this.mLeftTextView.setTextColor(color);
    }

    /**
     * 設定標題文字顏色
     * @param color
     */
    public void setTitleTextColor(int color) {
        this.mTitleTextView.setTextColor(color);
    }

    /**
     * 設定右側文字顏色
     * @param color
     */
    public void setRightTextColor(int color) {
        this.mRightTextView.setTextColor(color);
    }

    /**
     * 設定左側圖片
     * @param resId
     */
    public void setLeftImageResource(int resId) {
        this.mLeftImageView.setImageResource(resId);
    }

    /**
     * 設定右側圖片
     * @param resId
     */
    public void setRightImageResource(int resId) {
        this.mRightImageView.setImageResource(resId);
    }

    /**
     * 自定義標題欄介面
     */
    public interface TitleBarClickListener {
        public void onLeftClickListener();
        public void onRightClickListener();
    }
}

下面是在attrs.xml中自定義的屬性:
<!-- 自定義標題欄 -->
<declare-styleable name="CustomTitleBar">
    <!-- 兩側文字大小 -->
    <attr name="amboTextSize" format="dimension" />
    <attr name="textColor" format="color" />
    
    <!-- 左邊 -->
    <attr name="leftText" format="string" />
    <attr name="leftImage" format="reference" />
    <attr name="leftBackground" format="color|reference" />
    <attr name="leftVisible" format="boolean" />
    <!-- 標題 -->
    <attr name="titleText" format="string" /> />
    <attr name="titleTextSize" format="dimension"/>
    <!-- 右邊 -->
    <attr name="rightText" format="string" />
    <attr name="rightImage" format="reference" />
    <attr name="rightBackground" format="color|reference" />
    <attr name="rightVisible" format="boolean" />
</declare-styleable>

在Activity佈局檔案中的簡單使用:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    <strong><span style="color:#ff0000;">xmlns:titlebar="http://schemas.android.com/apk/res-auto"</span></strong>
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cce8cf"
    android:orientation="vertical">

    <strong><span style="color:#ff0000;"><aa.customtitlebar.ui.widget.CustomTitleBar
        android:id="@+id/id_ctb_main"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#ff5e4c"
        android:padding="10dp"
        titlebar:amboTextSize="16sp"
        titlebar:leftImage="@drawable/icon_back"
        titlebar:rightText="點一點"
        titlebar:textColor="#ffffff"
        titlebar:titleText="自定義標題欄"
        titlebar:leftVisible="true"
        titlebar:rightVisible="true"
        titlebar:titleTextSize="19sp" /></span></strong>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="50sp"
        android:gravity="center"
        android:textColor="#ff67800e"
        android:text="自定義標題欄"/>

</LinearLayout>

下面是標題欄的截圖: