1. 程式人生 > >Android自定義組合控制元件之實現CheckBox變化

Android自定義組合控制元件之實現CheckBox變化

前言:自定義組合控制元件最大的好處就是複用性,可以為我們節省不少程式碼量,但是一般我們自定義組合控制元件的時候,封裝出來的控制元件不管是自己用還是別人用也好,封裝的程式碼最好是易讀性強,便於修改,沒有必要封裝太多的屬性,一般控制在兩三個屬性為最佳,畢竟我們不是Google....!好了,扯得有點遠了,今天我帶領大家來封裝一個簡單易用的組合控制元件,讓你初步接觸如何自定義組合控制元件!

----------------------------分割線---------------------------

來看效果圖:


當然了,這個效果很簡單的,你不通過自定義組合控制元件也可以很輕鬆的實現。

----------------------------分割線---------------------------

實現:1. 寫一個類繼承RelativeLayout(ViewGroup)

2. 寫佈局檔案

3. 將佈局新增到RelativeLayout中(initView方法)

4. 增加api

5. 自定義屬性(1. values/attrs.xml, 2. 宣告名稱空間 , 3.在自定義view中配置屬性, 4. 在自定義view中載入屬性值 )

----------------------------分割線---------------------------

自定義屬性實現:

一:在values檔案下面新建一個attrs的檔案然後在裡面新增如下程式碼:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="SettingItemView">
        <attr name="title" format="string" />
        <attr name="desc_on" format="string" />
        <attr name="desc_off" format="string" />
    </declare-styleable>
</resources>
解釋:1.declare-styleable中的name是控制元件的類名。
2.attr裡面是控制元件的屬性,可新增字串,數值,布林值都可以新增。

二:在構造方法中獲取該屬性的值:

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SettingItemView);
String text = ta.getString(R.styleable.SettingItemView_title);

獲取這些值之後就可以做進一步的邏輯事件。

三:如何使用自定義控制元件:

1.在你佈局的最外層加入程式碼:

xmlns:app="http://schemas.android.com/apk/res-auto"
2.使用該屬性
  <com.fly.lsn29_groupview.SettingItemView
        android:id="@+id/siv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:desc_off="已經關閉"
        app:desc_on="已經開啟"
        app:title="設定" />
----------------------------分割線---------------------------

完整程式碼:

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class SettingItemView extends RelativeLayout {

    private TextView tvTitle;
    private TextView tvDesc;
    private CheckBox cbCheck;
    private String mDescOn;
    private String mDescOff;

    public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

    public SettingItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SettingItemView);
        String text = ta.getString(R.styleable.SettingItemView_title);
        mDescOn = ta.getString(R.styleable.SettingItemView_desc_on);
        mDescOff = ta.getString(R.styleable.SettingItemView_desc_off);
        ta.recycle();
        setTitle(text);
    }

    public SettingItemView(Context context) {
        super(context);
        initView();
    }

    /**
     * 初始化佈局
     */
    private void initView() {
        View child = View.inflate(getContext(), R.layout.setting_item_view, null);// 初始化組合控制元件佈局

        tvTitle = (TextView) child.findViewById(R.id.tv_title);
        tvDesc = (TextView) child.findViewById(R.id.tv_desc);
        cbCheck = (CheckBox) child.findViewById(R.id.cb_check);

        this.addView(child);// 將佈局新增給當前的RelativeLayout物件
    }

    /**
     * 設定標題
     *
     * @param title
     */
    public void setTitle(String title) {
        tvTitle.setText(title);
    }

    /**
     * 設定表述
     *
     * @param desc
     */
    public void setDesc(String desc) {
        tvDesc.setText(desc);
    }

    /**
     * 判斷是否勾選
     *
     * @return
     */
    public boolean isChecked() {
        return cbCheck.isChecked();
    }

    /**
     * 設定選中狀態
     *
     * @param checked
     */
    public void setChecked(boolean checked) {
        cbCheck.setChecked(checked);

        // 更新描述資訊
        if (checked) {
            setDesc(mDescOn);
        } else {
            setDesc(mDescOff);
        }
    }

}
涉及到的一個簡單佈局:
<?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="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="65dp"
        android:padding="5dp">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:text="標題"
            android:textColor="#000"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_title"
            android:layout_marginTop="3dp"
            android:text="描述"
            android:textColor="#a000"
            android:textSize="16sp" />

        <CheckBox
            android:id="@+id/cb_check"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:clickable="false"
            android:focusable="false"
            android:focusableInTouchMode="false" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignParentBottom="true"
            android:background="#494949" />
    </RelativeLayout>

</LinearLayout>
values資料夾下新建attrs檔案新增如下程式碼:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="SettingItemView">
        <attr name="title" format="string" />
        <attr name="desc_on" format="string" />
        <attr name="desc_off" format="string" />
    </declare-styleable>

</resources>
在佈局中使用:
<?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:gravity="center"
    android:orientation="vertical"
    tools:context="com.fly.lsn29_groupview.MainActivity">

    <com.fly.lsn29_groupview.SettingItemView
        android:id="@+id/siv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:desc_off="已經關閉"
        app:desc_on="已經開啟"
        app:title="設定" />

</LinearLayout>
在MainActivity中呼叫:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final SettingItemView siv = (SettingItemView) findViewById(R.id.siv);
        siv.setChecked(true);//初始化設定
        siv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (siv.isChecked()) {
                    siv.setChecked(false);
                    //處理邏輯
                } else {
                    siv.setChecked(true);
                    //處理邏輯
                }
            }
        });
    }
}
------------------------完!--------------------------