1. 程式人生 > >Android自定義複合控制元件

Android自定義複合控制元件

       在Android中,複合控制元件是非常常見的,下面以建立一個標題欄為例,講解建立自定義複合控制元件的過程。

       以下圖為例:我們要建立一個標題欄,這個標題欄是由左邊的Button、右邊的Button以及中間的TextView複合而成的,而我們希望能夠直接在這個自定義標題欄設定裡面的Button和TextView的屬性資訊。

       具體實現過程如下:

1、首先在res資源目錄的values目錄新建一個attrs.xml的屬性定義檔案,並在該檔案中定義相應的屬性。程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TopBar">
        <attr name="titleText" format="string" />
        <attr name="titleTextSize" format="dimension" />
        <attr name="titleTextColor" format="color" />
        <attr name="leftText" format="string" />
        <attr name="leftTextSize" format="dimension" />
        <attr name="leftTextColor" format="color" />
        <attr name="leftBackground" format="reference|color" />
        <attr name="rightText" format="string" />
        <attr name="rightTextSize" format="dimension" />
        <attr name="rightTextColor" format="color" />
        <attr name="rightBackground" format="reference|color" />
    </declare-styleable>
</resources>

       這裡定義了標題文字的內容、大小、顏色,左邊按鈕的文字內容、大小、顏色以及按鈕的背景,右邊按鈕的文字內容、大小、顏色以及按鈕的背景,值得一提的是,這裡的背景屬性既可以是顏色屬性,也可以是引用屬性,如引用一張圖片,故這裡使用了“|”來分隔不同的屬性——“reference|color”。 2、自定義的ComplexView程式碼如下:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ComplexView extends LinearLayout {
    private String titleText;//標題文字
    private float titleTextSize;//標題文字大小
    private int titleTextColor;//標題文字顏色

    private String leftText;//左邊按鈕文字
    private float leftTextSize;//左邊按鈕文字大小
    private int leftTextColor;//左邊按鈕文字顏色
    private Drawable leftBackground;//左邊按鈕背景

    private String rightText;//右邊按鈕文字
    private float rightTextSize;//右邊按鈕文字大小
    private int rightTextColor;//右邊按鈕文字顏色
    private Drawable rightBackground;//右邊按鈕背景

    private Button leftBtn;
    private TextView titleTv;
    private Button rightBtn;

    public ComplexView(Context context) {
        super(context);
    }

    public ComplexView(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.TopBar));
        View view = LayoutInflater.from(context).inflate(R.layout.complex_view, this);
        leftBtn = (Button) view.findViewById(R.id.left_btn);
        rightBtn = (Button) view.findViewById(R.id.right_btn);
        titleTv = (TextView) view.findViewById(R.id.title_tv);
        //設定標題屬性
        titleTv.setText(titleText);
        titleTv.setTextSize(titleTextSize);
        titleTv.setTextColor(titleTextColor);
        //設定左邊按鈕屬性
        leftBtn.setText(leftText);
        leftBtn.setTextSize(leftTextSize);
        leftBtn.setTextColor(leftTextColor);
        leftBtn.setBackgroundDrawable(leftBackground);
        //設定右邊按鈕屬性
        rightBtn.setText(rightText);
        rightBtn.setTextSize(rightTextSize);
        rightBtn.setTextColor(rightTextColor);
        rightBtn.setBackgroundDrawable(rightBackground);
        //左右按鈕點選事件
        leftBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onTopBarClickListener.leftClick();
            }
        });
        rightBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                onTopBarClickListener.rightClick();
            }
        });
    }

    //獲取自定義屬性集
    private void parseAttributes(TypedArray ta) {
        titleText = ta.getString(R.styleable.TopBar_titleText);
        titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 25);
        titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);

        leftText = ta.getString(R.styleable.TopBar_leftText);
        leftTextSize = ta.getDimension(R.styleable.TopBar_leftTextSize, 16);
        leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
        leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);

        rightText = ta.getString(R.styleable.TopBar_rightText);
        rightTextSize = ta.getDimension(R.styleable.TopBar_rightTextSize, 16);
        rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
        rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);

        ta.recycle();
    }

    //為左右按鈕設定點選事件,使用介面回撥方法
    public interface onTopBarClickListener {
        void leftClick();

        void rightClick();
    }

    onTopBarClickListener onTopBarClickListener = null;

    public void setOnTopBarClickListener(onTopBarClickListener onTopBarClickListener) {
        this.onTopBarClickListener = onTopBarClickListener;
    }
}

    其中complex_view佈局檔案如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/left_btn"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp" />

    <TextView
        android:id="@+id/title_tv"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center" />

    <Button
        android:id="@+id/right_btn"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp" />
</LinearLayout>

3、在activity_main中引入ComplexView,為了引用自定義控制元件的屬性,需要在activity_main佈局檔案中加入下面一句:

xmlns:app="http://schemas.android.com/apk/res-auto"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.exam.myapplication.ComplexView
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#008577"
        app:leftBackground="@drawable/btn_shape"
        app:leftText="返回"
        app:leftTextColor="#ffffff"
        app:leftTextSize="8sp"
        app:rightBackground="@drawable/btn_shape"
        app:rightText="更多"
        app:rightTextColor="#ffffff"
        app:rightTextSize="8sp"
        app:titleText="標題"
        app:titleTextColor="#ffffff"
        app:titleTextSize="10sp" />

</LinearLayout>

       上面的btn_shape其實是按鈕的背景,程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="3dp"/>
    <solid android:color="#00574B"/>
</shape>

4、我在自定義的ComplexView中還為左右按鈕增加了點選事件,這裡使用了介面回撥方法,可以在MainActivity中實現具體的邏輯。程式碼如下:

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity {
    ComplexView topBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        topBar = (ComplexView) findViewById(R.id.top_bar);
        topBar.setOnTopBarClickListener(new ComplexView.onTopBarClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void rightClick() {
                Toast.makeText(MainActivity.this, "更多", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

      建立自定義複合控制元件的整個流程到此介紹完畢。