Android-自定義項目通用Button

場景:經常在項目中高頻使用按鈕,比如 完成、下一步等有圓角且有按下效果的Button

思路:寫個自定義Button,編寫自定義屬性,方便在xml中設置圓角,顏色等屬性,按下的效果一般是用shape寫背景方式完成,爲了方便,shape不在xml編寫,改爲代碼編寫。

1.編寫自定義控件:

public class ShapeButton extends AppCompatButton {

    public ShapeButton(Context context) {
        this(context, null);
    }

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

    public ShapeButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

}

2.編寫自定義屬性:

   <declare-styleable name="ShapeButton">
       <!--按下的顏色-->
       <attr name="pressed_color" format="color" />
       <!--正常狀態顏色-->
       <attr name="normal_color" format="color" />
       <!--不可用的顏色-->
       <attr name="enabled_color" format="color" />
       <!--按鈕圓角半徑-->
       <attr name="radius_size" format="dimension" />
       <!--gravity-->
       <attr name="android:gravity" />
   </declare-styleable>

3.讀取自定義屬性:

    private int normal_color;
    private int pressed_color;
    private int enabled_color;
    private int gravity;
    private int radius_size;

   public ShapeButton(Context context, AttributeSet attrs, int defStyleAttr) {
       super(context, attrs, defStyleAttr);
       TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ShapeButton);
       normal_color = ta.getColor(R.styleable.ShapeButton_normal_color, Color.parseColor("#FF3333"));
       pressed_color = ta.getColor(R.styleable.ShapeButton_pressed_color, Color.parseColor("#CC3333"));
       enabled_color = ta.getColor(R.styleable.ShapeButton_enabled_color, Color.GRAY);
       radius_size = (int) ta.getDimension(R.styleable.ShapeButton_radius_size, dip2px(4));
       gravity = ta.getInt(R.styleable.ShapeButton_android_gravity, Gravity.CENTER);
       ta.recycle();
   }

4.爲控件賦值:

    private void init() {
        setGravity(gravity);
        setBackgroundDrawable(getStateListDrawable(getSolidRectDrawable(radius_size, pressed_color), getSolidRectDrawable(radius_size, normal_color)));
    }

   /**
    * 得到實心的drawable, 一般作爲選中,點中的效果
    *
    * @param cornerRadius 圓角半徑
    * @param solidColor   實心顏色
    * @return 得到實心效果
    */
   public static GradientDrawable getSolidRectDrawable(int cornerRadius, int solidColor) {
       GradientDrawable gradientDrawable = new GradientDrawable();
       // 設置矩形的圓角半徑
       gradientDrawable.setCornerRadius(cornerRadius);
       // 設置繪畫圖片色值
       gradientDrawable.setColor(solidColor);
       // 繪畫的是矩形
       gradientDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
       return gradientDrawable;
   }

   /**
    * 背景選擇器
    *
    * @param pressedDrawable 按下狀態的Drawable
    * @param normalDrawable  正常狀態的Drawable
    * @return 狀態選擇器
    */
   public StateListDrawable getStateListDrawable(Drawable pressedDrawable, Drawable normalDrawable) {
       StateListDrawable stateListDrawable = new StateListDrawable();
       stateListDrawable.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, pressedDrawable);
       stateListDrawable.addState(new int[]{android.R.attr.state_enabled}, normalDrawable);
       //設置不能用的狀態
       //默認其他狀態背景
       GradientDrawable gray = getSolidRectDrawable(radius_size, enabled_color);
       stateListDrawable.addState(new int[]{}, gray);
       return stateListDrawable;
   }

5.效果預覽

ShapeButton預覽

6.完整代碼:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.annotation.ColorInt;
import android.support.v7.widget.AppCompatButton;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;

import com.chao.baselib.R;


/**
 * Created by Chao on 2017/8/24.
 */

public class ShapeButton extends AppCompatButton {
    private int normal_color;
    private int pressed_color;
    private int enabled_color;
    private int gravity;
    private int radius_size;


    public ShapeButton(Context context) {
        this(context, null);
    }

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

    public ShapeButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ShapeButton);
        normal_color = ta.getColor(R.styleable.ShapeButton_normal_color, Color.parseColor("#FF3333"));
        pressed_color = ta.getColor(R.styleable.ShapeButton_pressed_color, Color.parseColor("#CC3333"));
        enabled_color = ta.getColor(R.styleable.ShapeButton_enabled_color, Color.GRAY);
        radius_size = (int) ta.getDimension(R.styleable.ShapeButton_radius_size, dip2px(4));
        gravity = ta.getInt(R.styleable.ShapeButton_android_gravity, Gravity.CENTER);
//        int textColor = attrs.getAttributeIntValue(
//                "http://schemas.android.com/apk/res/android", "textColor", Color.WHITE);
//        setTextColor(textColor);
        ta.recycle();
        TypedArray tar = getContext().obtainStyledAttributes(attrs, new int[]{android.R.attr.textColor, android.R.attr.paddingTop, android.R.attr.paddingBottom});
        if (tar != null) {
            setTextColor(tar.getColor(0, Color.WHITE));
            setPadding(6, (int) tar.getDimension(1, 8), 6, (int) tar.getDimension(2, 8));
        }
        setGravity(gravity);
        tar.recycle();
        init();
    }

    @Override
    public void setTextColor(@ColorInt int color) {
        super.setTextColor(color);
    }

    private void init() {
        setBackgroundDrawable(getStateListDrawable(getSolidRectDrawable(radius_size, pressed_color), getSolidRectDrawable(radius_size, normal_color)));
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        super.setPadding(dip2px(left), dip2px(top), dip2px(right), dip2px(bottom));
    }

    /**
     * 得到實心的drawable, 一般作爲選中,點中的效果
     *
     * @param cornerRadius 圓角半徑
     * @param solidColor   實心顏色
     * @return 得到實心效果
     */
    public static GradientDrawable getSolidRectDrawable(int cornerRadius, int solidColor) {
        GradientDrawable gradientDrawable = new GradientDrawable();
        // 設置矩形的圓角半徑
        gradientDrawable.setCornerRadius(cornerRadius);
        // 設置繪畫圖片色值
        gradientDrawable.setColor(solidColor);
        // 繪畫的是矩形
        gradientDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
        return gradientDrawable;
    }

    /**
     * 背景選擇器
     *
     * @param pressedDrawable 按下狀態的Drawable
     * @param normalDrawable  正常狀態的Drawable
     * @return 狀態選擇器
     */
    public StateListDrawable getStateListDrawable(Drawable pressedDrawable, Drawable normalDrawable) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, pressedDrawable);
        stateListDrawable.addState(new int[]{android.R.attr.state_enabled}, normalDrawable);
        //設置不能用的狀態
        //默認其他狀態背景
        GradientDrawable gray = getSolidRectDrawable(radius_size, enabled_color);
        stateListDrawable.addState(new int[]{}, gray);
        return stateListDrawable;
    }

    private int dip2px(float dpValue) {
        final float scale = getResources()
                .getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章