場景:經常在項目中高頻使用按鈕,比如 完成、下一步等有圓角且有按下效果的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.效果預覽
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);
}
}