StateListDrawable

1. GIF

StateListDrawable_第1张图片


2. 代码

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

    <com.unicorn.drawable.ColorButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp"
        android:text="登 录"
        android:textColor="@android:color/white"
        android:textSize="20dp"
        app:rb_background_color="@color/colorAccent"
        app:rb_corner_radius="2dp" />

    <com.unicorn.drawable.ColorButton
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp"
        android:text="登 录"
        android:textColor="@android:color/white"
        android:textSize="20dp"
        app:rb_background_color="@android:color/holo_green_light"
        app:rb_corner_radius="2dp" />

</LinearLayout>
<declare-styleable name="ColorButton">
        <attr name="rb_corner_radius" format="dimension" />
        <attr name="rb_background_color" format="color" />
    </declare-styleable>
public class ColorButton extends TextView {

    // PaintDrawable 可以画圆角,这个也行
    GradientDrawable defaultDrawable;
    GradientDrawable pressedDrawable;
    
    // 实现按下颜色变暗
    PorterDuffColorFilter pressedColorFilter;
    StateListDrawable background;

    public ColorButton(Context context) {
        super(context);
    }

    //

    float cornerRadius;
    int backgroundColor;

    public ColorButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorButton);
        float dp = typedArray.getDimension(R.styleable.ColorButton_rb_corner_radius, 0.0f);
        cornerRadius = dp2px(context, dp);
        backgroundColor = typedArray.getColor(R.styleable.ColorButton_rb_background_color, Color.GREEN);
        typedArray.recycle();

        defaultDrawable = new GradientDrawable();
        pressedDrawable = new GradientDrawable();
        pressedColorFilter = new PorterDuffColorFilter(Color.parseColor("#cccccc"), PorterDuff.Mode.MULTIPLY);
        background = new StateListDrawable();

        setClickable(true);
    }

    //

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        cornerRadius = Math.min(cornerRadius, getMeasuredHeight() / 2);
       
        defaultDrawable.setCornerRadius(cornerRadius);
        defaultDrawable.setColor(backgroundColor);
       
        pressedDrawable.setCornerRadius(cornerRadius);
        pressedDrawable.setColor(backgroundColor);
        pressedDrawable.setColorFilter(pressedColorFilter);
       
        background.addState(new int[]{-android.R.attr.state_pressed}, defaultDrawable);
        background.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);
        setBackground(background);
    }

    //

    protected int dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

}


3. StateListDrawable

调用链: View 状态改变,view.refreshDrawableState,,drawableStateChanged,drawable.setState,onStateChange

   @Override
    protected boolean onStateChange(int[] stateSet) {
        final boolean changed = super.onStateChange(stateSet);

        int idx = mStateListState.indexOfStateSet(stateSet);
        if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
                + Arrays.toString(stateSet) + " found " + idx);
        if (idx < 0) {
            idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
        }

        return selectDrawable(idx) || changed;
    }

就是当 View 状态变化时,改变 mCurrDrawable 并且重画。

    @Override
    public void draw(Canvas canvas) {
        if (mCurrDrawable != null) {
            mCurrDrawable.draw(canvas);
        }
        if (mLastDrawable != null) {
            mLastDrawable.draw(canvas);
        }
    }




你可能感兴趣的:(StateListDrawable)