在网上搜了很多相关的文章,大部分都是copy来copy去。也达不到项目的要求,所以就自己封装了一个RadioGroup。
先看效果:
实现方法也比较简单:
主要思路就是继承AppCompatRadioButton重写onDraw方法。根据RadioButton的宽高,利用画布(Canvas)和画笔(Paint)画一个矩形(Rect)。
下面就是具体的实现:
PeriodsButtonGroupView.java
public class PeriodsButtonGroupView extends RadioGroup {
private CharSequence[] mRadioButtonEntries;
private ColorStateList mRadioButtonTextColor;
public PeriodsButtonGroupView(Context context) {
super(context);
init(context);
}
public PeriodsButtonGroupView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PeriodsButtonGroupView);
mRadioButtonEntries = typedArray.getTextArray(R.styleable.PeriodsButtonGroupView_android_entries);
if (mRadioButtonEntries == null || mRadioButtonEntries.length == 0) {
mRadioButtonEntries = context.getResources().getStringArray(R.array.periods_button_group_entries);
}
mRadioButtonTextColor = typedArray.getColorStateList(R.styleable.PeriodsButtonGroupView_radioButtonTextColor);
if (mRadioButtonTextColor == null) {
mRadioButtonTextColor = getResources().getColorStateList(R.color.periods_radio_button_text_color_green);
}
typedArray.recycle();
init(context);
}
private void init(Context context) {
setOrientation(LinearLayout.HORIZONTAL);
initComponent(context);
}
private void initComponent(Context context) {
for (CharSequence charSequence : mRadioButtonEntries) {
PeriodsRadioButton radioButton = new PeriodsRadioButton(context);
radioButton.setLayoutParams(new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1));
radioButton.setTextAlignment(TEXT_ALIGNMENT_CENTER);
radioButton.setButtonDrawable(null);
radioButton.setTextColor(mRadioButtonTextColor);
radioButton.setText(charSequence);
addView(radioButton);
}
}
private static class PeriodsRadioButton extends AppCompatRadioButton {
private Paint mPaint;
public PeriodsRadioButton(Context context) {
super(context);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
}
public PeriodsRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PeriodsRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isChecked()) {
canvas.save();
float left = getMeasuredWidth() * 0.45f;
float right = getMeasuredWidth() * 0.55f;
float top = getMeasuredHeight() * 0.85f;
float bottom = getMeasuredHeight() * 0.95f;
mPaint.setColor(getCurrentTextColor());
canvas.drawRoundRect(left, top, right, bottom, 30, 30, mPaint);
canvas.restore();
}
}
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
invalidate();
}
}
}
periods_radio_button_text_color_green.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#00FF00"/>
<item android:state_pressed="true" android:color="#00FF00"/>
<item android:color="#888888"/>
</selector>
arrays.xml(如果不需要在布局文件中传入entries,可以直接在PeriodsButtonGroupView中hardcode)
<resources>
<string-array name="periods_button_group_entries">
<item>日</item>
<item>周</item>
<item>月</item>
<item>年</item>
</string-array>
</resources>
attrs.xml (如果不需要在布局文件中传入entries和color,可以直接在PeriodsButtonGroupView中hardcode)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PeriodsButtonGroupView">
<attr name="android:entries" />
<attr name="radioButtonTextColor" format="color|reference" />
</declare-styleable>
</resources>
调用的布局文件xml(如果不需要在布局文件中传入entries和color,可以直接在PeriodsButtonGroupView中hardcode,则不需要最后两行)
<com.xxx.xxx.PeriodsButtonGroupView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:radioButtonTextColor="@color/radio_button_text_color_green"
android:entries="@array/periods_button_group_entries"/>
注意的点:
1.点击RadioButton时,onDraw方法比点击时setChecked更快调用,所以要重写AppCompatRadioButton的setChecked方法去刷新控件。
2.Paint调用setAntiAlias(true)去锯齿(会有性能的损失)。
3.要调用Canvas的drawRoundRect方法,用drawRect来画的话是直角矩形,不美观。