1. 程式人生 > >android實現按鈕圓角點選背景、字型顏色都改變

android實現按鈕圓角點選背景、字型顏色都改變

實現圓角按鈕,點選的時候背景和字型的顏色都改變,這裡的實現效果如下:原狀態背景為白色,字型為藍色,當點選的時候背景為藍色,字型為白色。介紹兩種實現方式。1、使用button。2、實現自定義TextView。

1.使用Button首先在drawable下建一個Button背景的btn_bg_round_click.xml檔案。在這裡面設定Button原狀態和按下的時候,背景的顏色、圓角半徑、邊框寬度和顏色。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">
        <shape android:shape="rectangle" >
            <solid android:color="@color/color_white" />
            <corners android:radius="5dp" />
            <stroke android:width="1dp" android:color="#acacac" />
        </shape>
    </item>

    <item android:state_pressed="true" >
        <shape android:shape="rectangle">
            <solid android:color="@color/color_blue" />
            <corners android:radius="5dp" />
            <stroke android:width="1dp" android:color="#acacac" />
        </shape>
    </item>
</selector>

 再建一個改變字型顏色的btn_click_text_color.xml檔案。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" android:color="@color/color_blue"/>
    <item android:state_pressed="true" android:color="@color/color_white"/>
</selector>

最後在Button的background和textColor屬性中引用。

<Button
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@drawable/btn_bg_round_click"
        android:textColor="@drawable/selector_btn_click_text_color"
        android:text="登入"
        android:textSize="23sp"
        android:gravity="center" />

2. 實現自定義TextView

首先在values資料夾下建一個attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ButtonTextView">
        <attr name="pressTxtColor" format="color"></attr>
        <attr name="pressBgc" format="color"></attr>
        <attr name="stroke" format="dimension"></attr>
        <attr name="corner" format="dimension|fraction"></attr>
    </declare-styleable>
</resources>

再建一個ButtonTextView類,讓它繼承AppCompatTextView類

public class ButtonTextView extends AppCompatTextView {

    private final String NAME_SPACE = "http://schemas.android.com/apk/res/android";
    private final String ATTR_BGC = "background";
    private final String ATTR_TXTC = "textColor";

    private final int DEFAULT_TEXT_COLOR = 0x8a000000;
    //文字演策
    private int txtC = DEFAULT_TEXT_COLOR;
    private int pressTxtC = DEFAULT_TEXT_COLOR;
    //背景色
    private int bgc;
    private int pressBgc;
    //圓角
    private float corner;
    private float cornerPercent;
    //邊框
    private int stroke;

    /* 通過程式碼建立物件時,不檢索自定義屬性*/
    public ButtonTextView(Context context) {
        super(context);
        /*預設顏色*/
        setTextColor(DEFAULT_TEXT_COLOR);
    }

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

    public ButtonTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

        if (attrs != null) {
            String bc = attrs.getAttributeValue(NAME_SPACE, ATTR_BGC);
            if (TextUtils.isEmpty(bc)) {
                bgc = Color.WHITE;
            } else if (bc.startsWith("#")) {
                bgc = Color.parseColor(bc);
            } else if (bc.startsWith("@")) {
                bgc = ContextCompat.getColor(context, Integer.valueOf(bc.substring(1)));
            }

            String tc = attrs.getAttributeValue(NAME_SPACE, ATTR_TXTC);
            if (TextUtils.isEmpty(tc)) {
                txtC = DEFAULT_TEXT_COLOR;
            } else if (tc.startsWith("#")) {
                txtC = Color.parseColor(tc);
            } else if (tc.startsWith("@")) {
                txtC = ContextCompat.getColor(context, Integer.valueOf(tc.substring(1)));
            }

        }

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ButtonTextView);

        pressTxtC = ta.getColor(R.styleable.ButtonTextView_pressTxtColor, txtC);
        pressBgc = ta.getColor(R.styleable.ButtonTextView_pressBgc, bgc);

        //處理圓角度
        final String cornerValue = ta.getString(R.styleable.ButtonTextView_corner);
        if (!TextUtils.isEmpty(cornerValue)) {
            if (cornerValue.contains("%")) {
                corner = -1;
                cornerPercent = ta.getFraction(R.styleable.ButtonTextView_corner, 1, 1, 0f);
            } else {
                corner = ta.getDimensionPixelSize(R.styleable.ButtonTextView_corner, 0);
            }
        }

        //處理邊框
        stroke = ta.getDimensionPixelSize(R.styleable.ButtonTextView_stroke, 0);

        ta.recycle();
    }

    private void init() {
        setClickable(true);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (corner < 0) {
            corner = cornerPercent * h;
        }
        setBgcDrawable(bgc, pressBgc, corner, stroke);
        setTxtColor(txtC, pressTxtC);
    }

    /**
     * @param txtC      正常情況下的字型顏色
     * @param pressTxtC 按下時的字型顏色
     */
    private void setTxtColor(@NonNull int txtC, @NonNull int pressTxtC) {

        if (txtC == pressTxtC) {
            setTextColor(txtC);
            return;
        }

        int[] colors = new int[]{pressTxtC, txtC};

        int[][] states = new int[2][];
        states[0] = new int[]{android.R.attr.state_pressed};
        states[1] = new int[]{};

        ColorStateList colorStateList = new ColorStateList(states, colors);

        setTextColor(colorStateList);
    }


    /**
     * @param bgc      正常背景色
     * @param pressBgc 按下背景色
     * @param corner   圓角
     * @param stroke   邊框
     */
    private void setBgcDrawable(@NonNull int bgc, @NonNull int pressBgc, float corner, int stroke) {

        GradientDrawable bgcDrawable = new GradientDrawable();
        GradientDrawable pBgcDrawable = new GradientDrawable();

        bgcDrawable.setCornerRadius(corner);
        bgcDrawable.setStroke(stroke, txtC == 0 ? DEFAULT_TEXT_COLOR : txtC);
        bgcDrawable.setColor(bgc);


        if (bgc == pressBgc) {
            setBackgroundDrawable(bgcDrawable);
            return;
        }

        pBgcDrawable.setCornerRadius(corner);
        pBgcDrawable.setStroke(stroke, pressBgc);
        pBgcDrawable.setColor(pressBgc);

        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pBgcDrawable);
        stateListDrawable.addState(new int[]{}, bgcDrawable);

        setBackgroundDrawable(stateListDrawable);
    }

    /**
     * 設定背景色
     *
     * @param bgc
     * @param pressBgc
     */
    public void setBgcDrawable(@NonNull int bgc, @NonNull int pressBgc) {
        this.bgc = bgc;
        this.pressBgc = pressBgc;
    }

    /**
     * 設定文字顏色
     *
     * @param txtC
     * @param pressTxtC
     */
    public void setTextColor(@NonNull int txtC, @NonNull int pressTxtC) {
        this.txtC = txtC;
        this.pressTxtC = pressTxtC;
    }

    public void setCorner(float corner) {
        this.corner = corner;
    }

    public void setStroke(int stroke) {
        this.stroke = stroke;
    }

    public void setTxtC(int txtC, int pressTxtC) {
        this.txtC = txtC;
        this.pressTxtC = pressTxtC;
    }

}

最後在xml中使用,使用和普通的Button差不多。只不過在這裡面定義了一些按下時的效果屬性。pressBgc按下時背景的顏色。

pressTxtColor按下時字型顏色,stroke邊框寬度。

<com.geocompass.collect.view.ButtonTextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_margin="20dp"
        android:background="@color/color_white"
        android:gravity="center"
        android:text="登入"
        android:textSize="23sp"
        android:textColor="@color/color_blue"
        android:translationZ="3dp"
        app:corner="5dp"
        app:pressBgc="@color/color_blue"
        app:pressTxtColor="@color/color_white"
        app:stroke="1px" />