Android自定RadioGroup实现点击切换效果

来源:互联网 发布:java枚举类型的用法 编辑:程序博客网 时间:2024/06/05 12:33
一:.java文件
public class SegmentedGroup extends RadioGroup {    private int mMarginDp;    private Resources resources;    private int mTintColor;    private int mCheckedTextColor = Color.WHITE;    private LayoutSelector mLayoutSelector;    private Float mCornerRadius;    public SegmentedGroup(Context context) {        super(context);        resources = getResources();        mTintColor = resources.getColor(R.color.radio_button_selected_color);        mMarginDp = (int) getResources().getDimension(R.dimen.radio_button_stroke_border);        mCornerRadius = getResources().getDimension(R.dimen.radio_button_conner_radius);        mLayoutSelector = new LayoutSelector(mCornerRadius);    }    /* Reads the attributes from the layout */    private void initAttrs(AttributeSet attrs) {        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(                attrs,                R.styleable.SegmentedGroup,                0, 0);        try {            mMarginDp = (int) typedArray.getDimension(                    R.styleable.SegmentedGroup_sc_border_width,                    getResources().getDimension(R.dimen.radio_button_stroke_border));            mCornerRadius = typedArray.getDimension(                    R.styleable.SegmentedGroup_sc_corner_radius,                    getResources().getDimension(R.dimen.radio_button_conner_radius));            mTintColor = typedArray.getColor(                    R.styleable.SegmentedGroup_sc_tint_color,                    getResources().getColor(R.color.radio_button_selected_color));            mCheckedTextColor = typedArray.getColor(                    R.styleable.SegmentedGroup_sc_checked_text_color,                    getResources().getColor(android.R.color.white));        } finally {            typedArray.recycle();        }    }    public SegmentedGroup(Context context, AttributeSet attrs) {        super(context, attrs);        resources = getResources();        mTintColor = resources.getColor(R.color.radio_button_selected_color);        mMarginDp = (int) getResources().getDimension(R.dimen.radio_button_stroke_border);        mCornerRadius = getResources().getDimension(R.dimen.radio_button_conner_radius);        initAttrs(attrs);        mLayoutSelector = new LayoutSelector(mCornerRadius);    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        //Use holo light for default        updateBackground();    }    public void setTintColor(int tintColor) {        mTintColor = tintColor;        updateBackground();    }    public void setTintColor(int tintColor, int checkedTextColor) {        mTintColor = tintColor;        mCheckedTextColor = checkedTextColor;        updateBackground();    }    public void updateBackground() {        int count = super.getChildCount();        for (int i = 0; i < count; i++) {            View child = getChildAt(i);            updateBackground(child);            // If this is the last view, don't set LayoutParams            if (i == count - 1) break;            LayoutParams initParams = (LayoutParams) child.getLayoutParams();            LayoutParams params = new LayoutParams(initParams.width, initParams.height, initParams.weight);            // Check orientation for proper margins            if (getOrientation() == LinearLayout.HORIZONTAL) {                params.setMargins(0, 0, -mMarginDp, 0);            } else {                params.setMargins(0, 0, 0, -mMarginDp);            }            child.setLayoutParams(params);        }    }    @SuppressLint("NewApi") private void updateBackground(View view) {        int checked = mLayoutSelector.getSelected();        int unchecked = mLayoutSelector.getUnselected();        //Set text color        ColorStateList colorStateList = new ColorStateList(new int[][]{                {android.R.attr.state_pressed},                {-android.R.attr.state_pressed, -android.R.attr.state_checked},                {-android.R.attr.state_pressed, android.R.attr.state_checked}},                new int[]{Color.GRAY, mTintColor, mCheckedTextColor});        ((Button) view).setTextColor(colorStateList);        //Redraw with tint color        Drawable checkedDrawable = resources.getDrawable(checked).mutate();        Drawable uncheckedDrawable = resources.getDrawable(unchecked).mutate();        ((GradientDrawable) checkedDrawable).setColor(mTintColor);        ((GradientDrawable) checkedDrawable).setStroke(mMarginDp, mTintColor);        ((GradientDrawable) uncheckedDrawable).setStroke(mMarginDp, mTintColor);        //Set proper radius        ((GradientDrawable) checkedDrawable).setCornerRadii(mLayoutSelector.getChildRadii(view));        ((GradientDrawable) uncheckedDrawable).setCornerRadii(mLayoutSelector.getChildRadii(view));        //Create drawable        StateListDrawable stateListDrawable = new StateListDrawable();        stateListDrawable.addState(new int[]{-android.R.attr.state_checked}, uncheckedDrawable);        stateListDrawable.addState(new int[]{android.R.attr.state_checked}, checkedDrawable);        //Set button background        if (Build.VERSION.SDK_INT >= 16) {            view.setBackground(stateListDrawable);        } else {            view.setBackgroundDrawable(stateListDrawable);        }    }    /*     * This class is used to provide the proper layout based on the view.     * Also provides the proper radius for corners.     * The layout is the same for each selected left/top middle or right/bottom button.     * float tables for setting the radius via Gradient.setCornerRadii are used instead     * of multiple xml drawables.     */    private class LayoutSelector {        private int children;        private int child;        private final int SELECTED_LAYOUT = R.drawable.radio_checked;        private final int UNSELECTED_LAYOUT = R.drawable.radio_unchecked;        private float r;    //this is the radios read by attributes or xml dimens        private final float r1 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP                , 0.1f, getResources().getDisplayMetrics());    //0.1 dp to px        private final float[] rLeft;    // left radio button        private final float[] rRight;   // right radio button        private final float[] rMiddle;  // middle radio button        private final float[] rDefault; // default radio button        private final float[] rTop;     // top radio button        private final float[] rBot;     // bot radio button        private float[] radii;          // result radii float table        public LayoutSelector(float cornerRadius) {            children = -1; // Init this to force setChildRadii() to enter for the first time.            child = -1; // Init this to force setChildRadii() to enter for the first time            r = cornerRadius;            rLeft = new float[]{r, r, r1, r1, r1, r1, r, r};            rRight = new float[]{r1, r1, r, r, r, r, r1, r1};            rMiddle = new float[]{r1, r1, r1, r1, r1, r1, r1, r1};            rDefault = new float[]{r, r, r, r, r, r, r, r};            rTop = new float[]{r, r, r, r, r1, r1, r1, r1};            rBot = new float[]{r1, r1, r1, r1, r, r, r, r};        }        private int getChildren() {            return SegmentedGroup.this.getChildCount();        }        private int getChildIndex(View view) {            return SegmentedGroup.this.indexOfChild(view);        }        private void setChildRadii(int newChildren, int newChild) {            // If same values are passed, just return. No need to update anything            if (children == newChildren && child == newChild)                return;            // Set the new values            children = newChildren;            child = newChild;            // if there is only one child provide the default radio button            if (children == 1) {                radii = rDefault;            } else if (child == 0) { //left or top                radii = (getOrientation() == LinearLayout.HORIZONTAL) ? rLeft : rTop;            } else if (child == children - 1) {  //right or bottom                radii = (getOrientation() == LinearLayout.HORIZONTAL) ? rRight : rBot;            } else {  //middle                radii = rMiddle;            }        }        /* Returns the selected layout id based on view */        public int getSelected() {            return SELECTED_LAYOUT;        }        /* Returns the unselected layout id based on view */        public int getUnselected() {            return UNSELECTED_LAYOUT;        }        /* Returns the radii float table based on view for Gradient.setRadii()*/        public float[] getChildRadii(View view) {            int newChildren = getChildren();            int newChild = getChildIndex(view);            setChildRadii(newChildren, newChild);            return radii;        }    }}
二:Drawable配置资源
(1)button_text_color.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true" android:color="#DDd4d4d4"/>    <item android:state_checked="false" android:state_pressed="false" android:color="@color/radio_button_selected_color"/>    <item android:state_checked="true" android:state_pressed="false" android:color="#fff2f2f2"/></selector>
(2)radio_checked.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:padding="10dp"    android:shape="rectangle">    <!-- you can use any color you want I used here gray color-->    <solid android:color="@color/radio_button_selected_color" />    <stroke        android:width="@dimen/radio_button_stroke_border"        android:color="@color/radio_button_selected_color" /></shape>
(3)radio_unchecked.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle"    android:padding="10dp">    <!-- you can use any color you want I used here gray color-->    <solid android:color="@color/radio_button_unselected_color" />    <stroke        android:width="@dimen/radio_button_stroke_border"        android:color="@color/radio_button_selected_color" /></shape>
三:attrs配置资源
<?xml version="1.0" encoding="utf-8"?><resources>         <declare-styleable name="SegmentedGroup">        <attr name="sc_corner_radius" format="dimension" />        <attr name="sc_border_width" format="dimension" />        <attr name="sc_tint_color" format="color" />        <attr name="sc_checked_text_color" format="color" />    </declare-styleable></resources>
四:colors配置资源
<resources>    <color name="colorPrimary">#3F51B5</color>    <color name="colorPrimaryDark">#303F9F</color>    <color name="colorAccent">#FF4081</color>         <color name="radio_button_selected_color">#ff33b5e5</color>    <color name="radio_button_unselected_color">@android:color/transparent</color></resources>
五:dimens配置资源
<resources>    <!-- Default screen margins, per the Android Design guidelines. -->    <dimen name="activity_horizontal_margin">16dp</dimen>    <dimen name="activity_vertical_margin">16dp</dimen>    <!--自定义控件SegmentetGroup-->    <dimen name="radio_button_conner_radius">5dp</dimen>    <dimen name="radio_button_stroke_border">1dp</dimen></resources>
六:styles配置资源
<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style>    <!-- 自定义RadioButton -->    <style name="RadioButton">        <item name="android:textColor">@drawable/button_text_color</item>        <item name="android:minHeight">33dp</item>        <item name="android:minWidth">70dp</item>        <item name="android:gravity">center</item>        <item name="android:button">@null</item>        <item name="android:paddingLeft">5dp</item>        <item name="android:paddingRight">5dp</item>    </style></resources> 
七:使用布局文件
<com.toocms.switchbutton1.SegmentedGroup    android:layout_width="wrap_content"    android:layout_height="match_parent"    android:orientation="horizontal"    android:layout_centerInParent="true"    android:paddingTop="10dp"    android:paddingBottom="10dp"    android:fadingEdge="none">    <RadioButton        android:id="@+id/circle_search"        style="@style/RadioButton"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1"        android:checked="true"        android:gravity="center"        android:text="发现" />    <RadioButton        android:id="@+id/circle_attention"        style="@style/RadioButton"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1"        android:gravity="center"        android:text="关注" /></com.toocms.switchbutton1.SegmentedGroup>

八:截图
1 0
原创粉丝点击