效果图

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实例状态的保存与恢复的更多相关文章

  1. Android笔记之自定义对话框

    效果如下图 对话框布局 dialog_uninstallation_confirmation.xml <?xml version="1.0" encoding="u ...

  2. Android笔记之自定义PopupWindow

    效果图 popup_window_addition.xml <?xml version="1.0" encoding="utf-8"?> <L ...

  3. Android之Activity状态的保存和恢复

    系统在某些情况下会调用onSaveInstanceState()和onRestoreInstanceState() 这两个方法来保存和恢复Activity的状态. 一句话:Activity在" ...

  4. Android开发中Activity状态的保存与恢复

    当置于后台的Activity因内存紧张被系统自动回收的时候,再次启动它的话他会重新调用onCretae()从而丢失了之前置于后台前的状态. 这时候就要重写Activity的两个方法来保存和恢复状态,具 ...

  5. 保存和恢复 Android Fragment 的状态

    经过几年在 Android 应用开发中应用 Fragment 的努力之后,我必须要说尽管Fragment的概念非常优秀,但是它也同时带来了一堆问题.当我们处理实例的状态保存时就需要特别一件一件地修护好 ...

  6. React Native之(支持iOS与Android)自定义单选按钮(RadioGroup,RadioButton)

    React Native之(支持iOS与Android)自定义单选按钮(RadioGroup,RadioButton) 一,需求与简单介绍 在开发项目时发现RN没有给提供RadioButton和Rad ...

  7. 【Android自定义控件】支持多层嵌套RadioButton的RadioGroup

    前言 非常喜欢用RadioButton+RadioGroup做Tabs,能自动处理选中等效果,但是自带的RadioGroup不支持嵌套RadioButton(从源码可看出仅仅是判断子控件是不是Radi ...

  8. android单选按钮选择,RadioGroup,radioButton

    android单选按钮选择,RadioGroup,radioButton 14. 四 / android基础 / 没有评论   单选布局绑定 如何识别选择

  9. Android RadioGroup/RadioButton

    RadioGroup      RadioButton的集合,提供多选一的机制      属性:   android:orientation="horizontal/vertical&quo ...

随机推荐

  1. 2017.4.26 慕课网--Java 高并发秒杀API(一)

    Java高并发秒杀API系列(一) -----------------业务分析及Dao层 第一章 课程介绍 1.1 内容介绍及业务分析 (1)课程内容 SSM框架的整合使用 秒杀类系统需求理解和实现 ...

  2. Solidworks 好的测试题模拟题

    题目:按照下图构建草图,注意设置必要的几何约束. 问题:   1.参照下图所示参数时请问其中绿色区域的面积为多少平方毫米?     题目:参照下图绘制草图轮廓,注意图中各线条之间均为相切过渡. 问题: ...

  3. Beautiful Soup 4.4.0 基本使用方法

    Beautiful Soup 4.4.0 基本使用方法Beautiful Soup 安装 pip install  beautifulsoup4 标准库有html.parser解析器但速度不是很快一般 ...

  4. Laravel之事件

    一.事件 事件无处不在,比如用户登录.购买商品.搜索.查看文章,等等,都是事件,有了事件,就有事件监听器,事件监听器监听到事件发生后会执行一些操作,Laravel使用观察者模式来实现这种监听机制.本节 ...

  5. 内容提供器(ContentProvider)

    一.简介内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性.目前,使 ...

  6. flex布局 (回顾)

    1.父元素 属性 display:flex; // 必写 justify-content: XXX; // 设置子容器沿主轴排列 align-items: XXX; // 设置子容器如何沿交叉轴排列 ...

  7. WebService的缓存机制

    分类: .NET ASP 2010-11-13 10:00 849人阅读 评论(0) 收藏 举报 webservicestring数据库nullapplicationweb服务 WebService的 ...

  8. 操作REDIES

    import redis r=redis.Redis(host='118.XX.XX.XXX',password='XXXXXXX9*',db=1,port=6379) # 增删改查r.set('jd ...

  9. Spring使用经验之StandardServletMultipartResolver实现文件上传的基本配置

    Note:Spring使用版本是4.1.6.RELEASE 1. 在实现了AbstractAnnotationConfigDispatcherServletInitializer的类中重载custom ...

  10. 【JQuery Easy UI】后台管理系统的简单布局分享

    重要说明:本博已迁移到 石佳劼的博客.有疑问请到 文章新地址 留言..! 近期做的一个简单的后台管理系统,当中用到了JQuery Easy UI框架,对于撸主这样的把控件能摆整齐就谢天谢地的码农来说, ...