Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复

效果图

Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复

activity_main.xml

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.bu_ish.custom_radio_button.RadioGroup
        android:id="@+id/rgTab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:checkedButton="@id/urbApproved">

        <com.bu_ish.custom_radio_button.UnderlineRadioButton
            android:id="@+id/urbAll"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:text="全部"
            app:textColorChecked="@color/colorPrimary"
            app:textColorUnchecked="#55000000"
            app:textMarginBottom="3dp"
            app:textMarginTop="3dp"
            app:underlineColorChecked="@color/colorPrimary"
            app:underlineColorUnchecked="@android:color/transparent"
            app:underlineHeight="3dp" />

        <com.bu_ish.custom_radio_button.UnderlineRadioButton
            android:id="@+id/urbApproved"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:text="已通过"
            app:textColorChecked="@color/colorPrimary"
            app:textColorUnchecked="#55000000"
            app:textMarginBottom="3dp"
            app:textMarginTop="3dp"
            app:underlineColorChecked="@color/colorPrimary"
            app:underlineColorUnchecked="@android:color/transparent"
            app:underlineHeight="3dp" />

        <com.bu_ish.custom_radio_button.UnderlineRadioButton
            android:id="@+id/urbVerifying"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:text="审核中"
            app:textColorChecked="@color/colorPrimary"
            app:textColorUnchecked="#55000000"
            app:textMarginBottom="3dp"
            app:textMarginTop="3dp"
            app:underlineColorChecked="@color/colorPrimary"
            app:underlineColorUnchecked="@android:color/transparent"
            app:underlineHeight="3dp" />
    </com.bu_ish.custom_radio_button.RadioGroup>

    <TextView
        android:id="@+id/tvContent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:text="已通过" />
</LinearLayout>

MainActivity.java

package com.bu_ish.custom_radio_button;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private RadioGroup rgTab;
    private TextView tvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rgTab = findViewById(R.id.rgTab);
        tvContent = findViewById(R.id.tvContent);
        rgTab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(int checkedId) {
                switch (checkedId) {
                    case R.id.urbAll:
                        tvContent.setText("全部");
                        break;
                    case R.id.urbApproved:
                        tvContent.setText("已通过");
                        break;
                    case R.id.urbVerifying:
                        tvContent.setText("审核中");
                }
            }
        });
    }
}

RadioGroup.java

package com.bu_ish.custom_radio_button;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class RadioGroup extends LinearLayout {
    private int checkedId;
    private OnCheckedChangeListener onCheckedChangeListener;
    private static final String KEY_SUPER_PARCELABLE = "SuperParcelableKey";
    private static final String KEY_CHECKED_ID = "CheckedIdKey";

    public RadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RadioGroup);
        checkedId = typedArray.getResourceId(R.styleable.RadioGroup_checkedButton, NO_ID);
        typedArray.recycle();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (checkedId != NO_ID) {
            setCheckedStateForView(checkedId, true);
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superParcelable = super.onSaveInstanceState();
        Bundle bundle = new Bundle();
        bundle.putParcelable(KEY_SUPER_PARCELABLE, superParcelable);
        bundle.putInt(KEY_CHECKED_ID, checkedId);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        Bundle bundle = (Bundle) state;
        super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_PARCELABLE));
        int id = bundle.getInt(KEY_CHECKED_ID);
        check(id);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        UnderlineRadioButton button = (UnderlineRadioButton) child;
        if (button.isChecked()) {
            int buttonId = button.getId();
            if (buttonId != checkedId) {
                setCheckedId(buttonId);
                if (checkedId != NO_ID) {
                    setCheckedStateForView(checkedId, false);
                }
            }
        }
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                int id = v.getId();
                if (id != checkedId) {
                    check(id);
                }
            }
        });
        super.addView(child, index, params);
    }

    public void check(int id) {
        if (id != checkedId) {
            setCheckedStateForView(checkedId, false);
            setCheckedStateForView(id, true);
            setCheckedId(id);
        }
    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        onCheckedChangeListener = listener;
    }

    private void setCheckedStateForView(int viewId, boolean checked) {
        UnderlineRadioButton button = findViewById(viewId);
        button.setChecked(checked);
    }

    private void setCheckedId(int id) {
        checkedId = id;
        if (onCheckedChangeListener != null) {
            onCheckedChangeListener.onCheckedChanged(id);
        }
    }

    public interface OnCheckedChangeListener {
        void onCheckedChanged(int checkedId);
    }
}

UnderlineRadioButton.java

package com.bu_ish.custom_radio_button;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

public class UnderlineRadioButton extends FrameLayout {
    private TextView tvText;
    private View underline;
    private int textColorChecked, textColorUnchecked;
    private int underlineColorChecked, underlineColorUnchecked;
    private boolean checked;

    public UnderlineRadioButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UnderlineRadioButton);
        LinearLayout ll = new LinearLayout(context);
        ll.setOrientation(LinearLayout.VERTICAL);
        LayoutParams llLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        llLayoutParams.gravity = Gravity.CENTER;
        tvText = new TextView(context);
        String text = typedArray.getString(R.styleable.UnderlineRadioButton_text);
        tvText.setText(text);
        LinearLayout.LayoutParams tvTextLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        tvTextLayoutParams.gravity = Gravity.CENTER;
        tvTextLayoutParams.topMargin = typedArray.getDimensionPixelSize(R.styleable.UnderlineRadioButton_textMarginTop, 0);
        tvTextLayoutParams.bottomMargin = typedArray.getDimensionPixelSize(R.styleable.UnderlineRadioButton_textMarginBottom, 0);
        ll.addView(tvText, tvTextLayoutParams);
        underline = new View(context);
        int underlineHeight = typedArray.getDimensionPixelSize(R.styleable.UnderlineRadioButton_underlineHeight, 0);
        LinearLayout.LayoutParams underlineLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, underlineHeight);
        ll.addView(underline, underlineLayoutParams);
        addView(ll, llLayoutParams);
        boolean checked = typedArray.getBoolean(R.styleable.UnderlineRadioButton_checked, false);
        textColorChecked = typedArray.getColor(R.styleable.UnderlineRadioButton_textColorChecked, 0);
        textColorUnchecked = typedArray.getColor(R.styleable.UnderlineRadioButton_textColorUnchecked, 0);
        underlineColorChecked = typedArray.getColor(R.styleable.UnderlineRadioButton_underlineColorChecked, 0);
        underlineColorUnchecked = typedArray.getColor(R.styleable.UnderlineRadioButton_underlineColorUnchecked, 0);
        setChecked(checked);
        typedArray.recycle();
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
        if (checked) {
            tvText.setTextColor(textColorChecked);
            underline.setBackgroundColor(underlineColorChecked);
        } else {
            tvText.setTextColor(textColorUnchecked);
            underline.setBackgroundColor(underlineColorUnchecked);
        }
    }
}

P.S.

onSaveInstanceState用于保存实例状态

onRestoreInstanceState用于恢复实例状态

onFinishInflate,完成填充的回调

完整Demo链接:https://pan.baidu.com/s/1E_kQoVaatxFMdstfzw8oZw,提取码:rg9c

Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复

上一篇:springmvc编码问题


下一篇:Python Special Syntax 8: 序列化与反序列化-->华丽丽的叫 pickle(泡菜?!)