效果图
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