可设置圆角背景边框的的按钮, 通过调节色彩明度自动计算按下(pressed)状态颜色



可设置圆角背景边框的按钮, 通过调节色彩明度自动计算按下(pressed)状态颜色_sed



使用:


xml

<?xml version="1.0" encoding="UTF-8"?><LinearLayout android:paddingTop="20dp" android:orientation="vertical" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">


<LinearLayout android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="match_parent">

<com.github.czy1121.view.RoundButton app:btnSolidColor="#3F51B5" app:btnPressedRatio="0.8" app:btnCornerRadius="10dp" android:text="Text" style="@style/RoundButton"/>

<com.github.czy1121.view.RoundButton app:btnSolidColor="#9C27B0" app:btnPressedRatio="0.8" app:btnCornerRadius="stadium" android:text="Text" style="@style/RoundButton"/>

<com.github.czy1121.view.RoundButton app:btnSolidColor="#03A9F4" app:btnPressedRatio="0.8" app:btnCornerRadius="stadium" android:text="Text" style="@style/RoundButton"/>

<com.github.czy1121.view.RoundButton app:btnSolidColor="#4CAF50" app:btnPressedRatio="0.9" app:btnCornerRadius="10dp" android:text="Text" style="@style/RoundButton" android:enabled="false"/>

<com.github.czy1121.view.RoundButton android:layout_height="50dp" android:layout_width="50dp" app:btnSolidColor="@color/bg" app:btnPressedRatio="0.9" app:btnCornerRadius="stadium" android:text="Text" style="@style/RoundButton" android:layout_weight="0"/>

</LinearLayout>


<LinearLayout android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="match_parent" android:background="#CDDC39">

<com.github.czy1121.view.RoundButton app:btnPressedRatio="1.5" app:btnCornerRadius="10dp" android:text="Text" style="@style/RoundButton.Two" app:btnStrokeColor="#3F51B5" android:textColor="#3F51B5"/>

<com.github.czy1121.view.RoundButton app:btnPressedRatio="0.5" app:btnCornerRadius="stadium" android:text="Text" style="@style/RoundButton.Two" app:btnStrokeColor="#9C27B0" android:textColor="#9C27B0" app:btnStrokeDashWidth="6dp" app:btnStrokeDashGap="3dp"/>

<com.github.czy1121.view.RoundButton app:btnPressedRatio="0.9" app:btnCornerRadius="stadium" android:text="Text" style="@style/RoundButton.Two" app:btnStrokeColor="#03A9F4" android:textColor="#03A9F4"/>

<com.github.czy1121.view.RoundButton app:btnPressedRatio="0.9" app:btnCornerRadius="10dp" android:text="Text" style="@style/RoundButton.Two" app:btnStrokeColor="#4CAF50" android:textColor="#4CAF50"/>

</LinearLayout>

</LinearLayout>




import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.TextView;

import com.github.czy1121.roundbutton.R;


public final class RoundButton extends TextView {
    public RoundButton(Context context) {
        this(context, null);
    }

    public RoundButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);


        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundButton);

        float pressedRatio = a.getFloat(R.styleable.RoundButton_btnPressedRatio, 0.80f);
        int cornerRadius = a.getLayoutDimension(R.styleable.RoundButton_btnCornerRadius, 0);

        ColorStateList solidColor = a.getColorStateList(R.styleable.RoundButton_btnSolidColor);
        int strokeColor = a.getColor(R.styleable.RoundButton_btnStrokeColor, 0x0);
        int strokeWidth = a.getDimensionPixelSize(R.styleable.RoundButton_btnStrokeWidth, 0);
        int strokeDashWidth = a.getDimensionPixelSize(R.styleable.RoundButton_btnStrokeDashWidth, 0);
        int strokeDashGap = a.getDimensionPixelSize(R.styleable.RoundButton_btnStrokeDashGap, 0);

        a.recycle();

        setSingleLine(true);
        setGravity(Gravity.CENTER);

        RoundDrawable rd = new RoundDrawable(cornerRadius == -1);
        rd.setCornerRadius(cornerRadius == -1 ? 0 : cornerRadius);
        rd.setStroke(strokeWidth, strokeColor, strokeDashWidth, strokeDashGap);

        if (solidColor == null) {
            solidColor = ColorStateList.valueOf(0);
        }
        if (solidColor.isStateful()) {
            rd.setSolidColors(solidColor);
        } else if (pressedRatio > 0.0001f) {
            rd.setSolidColors(csl(solidColor.getDefaultColor(), pressedRatio));
        } else {
            rd.setColor(solidColor.getDefaultColor());
        }
        setBackground(rd);
    }

    // 灰度
    int greyer(int color) {
        int blue = (color & 0x000000FF) >> 0;
        int green = (color & 0x0000FF00) >> 8;
        int red = (color & 0x00FF0000) >> 16;
        int grey = Math.round(red * 0.299f + green * 0.587f + blue * 0.114f);
        return Color.argb(0xff, grey, grey, grey);
    }

    // 明度
    int darker(int color, float ratio) {
        color = (color >> 24) == 0 ? 0x22808080 : color;
        float[] hsv = new float[3];
        Color.colorToHSV(color, hsv);
        hsv[2] *= ratio;
        return Color.HSVToColor(color >> 24, hsv);
    }

    ColorStateList csl(int normal, float ratio) {
        //        int disabled = greyer(normal);
        int pressed = darker(normal, ratio);
        int[][] states = new int[][]{{android.R.attr.state_pressed}, {}};
        int[] colors = new int[]{pressed, normal};
        return new ColorStateList(states, colors);
    }

    private static class RoundDrawable extends GradientDrawable {
        private boolean mIsStadium = false;

        private ColorStateList mSolidColors;
        private int mFillColor;

        public RoundDrawable(boolean isStadium) {
            mIsStadium = isStadium;
        }

        public void setSolidColors(ColorStateList colors) {
            mSolidColors = colors;
            setColor(colors.getDefaultColor());
        }

        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            if (mIsStadium) {
                RectF rect = new RectF(getBounds());
                setCornerRadius((rect.height() > rect.width() ? rect.width() : rect.height()) / 2);
            }
        }

        @Override
        public void setColor(int argb) {
            mFillColor = argb;
            super.setColor(argb);
        }

        @Override
        protected boolean onStateChange(int[] stateSet) {
            if (mSolidColors != null) {
                final int newColor = mSolidColors.getColorForState(stateSet, 0);
                if (mFillColor != newColor) {
                    setColor(newColor);
                    return true;
                }
            }
            return false;
        }

        @Override
        public boolean isStateful() {
            return super.isStateful() || (mSolidColors != null && mSolidColors.isStateful());
        }
    }
}




<declare-styleable name="RoundButton"><!-- 背景色 -->


<attr name="btnSolidColor" format="color"/>

<!-- 边框色 -->


<attr name="btnStrokeColor" format="color"/>

<!-- 边框厚度 -->


<attr name="btnStrokeWidth" format="dimension"/>

<!-- 边框虚线长度 -->


<attr name="btnStrokeDashWidth" format="dimension"/>

<!-- 边框虚线间隙 -->


<attr name="btnStrokeDashGap" format="dimension"/>

<!-- 圆角半径,stadium 表示半径为 min(height,width) / 2-->



<attr name="btnCornerRadius" format="dimension">

<enum name="stadium" value="-1"/>

</attr>

<!-- 自动计算按下(pressed)状态颜色的系数, 值为0时不自动计算 -->


<attr name="btnPressedRatio" format="float"/>

</declare-styleable>



https://github.com/czy1121/roundbutton

  • 可设置圆角背景边框的按钮, 通过调节色彩明度自动计算按下(pressed)状态颜色_github_02

  • 大小: 37.3 KB
  • 查看图片附件