FlatButton


关键就是实现平滑地改变上层 chlid drawable 的 inset。

平滑,又是 Scroller 那一套,重画后要求重画自己。

今天从书上看到,重画间隔是 16 毫秒。


TransationDrawable 是改变透明度,Scroller 是改变 mScrollX,这里是要改变 inset。

本质是一样的,利用重画间隔,不断重画,达到平滑的效果。

public class BottomInsetTransitionDrawable extends LayerDrawable {

    private double bottomHeight;

    public BottomInsetTransitionDrawable(Drawable[] layers, int bottomHeight) {
        super(layers);
        this.bottomHeight = bottomHeight;
        mBottomInset = bottomHeight;
    }

    //

    private static final int TRANSITION_STARTING = 0;

    private static final int TRANSITION_RUNNING = 1;

    private static final int TRANSITION_NONE = 2;

    private int mTransitionState = TRANSITION_NONE;

    private long mStartTimeMillis;

    private int mDuration;

    // 实际底部内边距
    private double mBottomInset;

    public void startTransition(int durationMillis) {
        mDuration = durationMillis;
        mTransitionState = TRANSITION_STARTING;
        invalidateSelf();
    }

    public void resetTransition() {
        mBottomInset = bottomHeight;
        mTransitionState = TRANSITION_NONE;
        invalidateSelf();
    }

    //

    @Override
    public void draw(Canvas canvas) {

        setLayerInset(1, 0, 0, 0, (int) mBottomInset);
        // 改变 child 的 bounds
        onBoundsChange(getBounds());
        // 重绘所有 child drawable
        super.draw(canvas);

        Log.e("重画", mBottomInset + " " + mTransitionState);

        switch (mTransitionState) {
            case TRANSITION_STARTING:
                mStartTimeMillis = SystemClock.uptimeMillis();
                mTransitionState = TRANSITION_RUNNING;
                break;
            case TRANSITION_RUNNING:
                if (mStartTimeMillis >= 0) {
                    float normalized = (float) (SystemClock.uptimeMillis() - mStartTimeMillis) / mDuration;
                    normalized = Math.min(normalized, 1.0f);
                    // 根据时间流逝,改变底部内边距
                    mBottomInset = (1 - normalized) * mBottomInset;
                }
                break;
        }
        if (mTransitionState == TRANSITION_RUNNING && mBottomInset != 0) {
            // 重画后要求下一次重画,时间间隔 16ms
            invalidateSelf();
        }
    }

    //

    @Override
    public boolean isStateful() {
        return true;
    }

    @Override
    protected boolean onStateChange(int[] state) {
        if (isStatePressed(state)) {
            // 本来是设置 1000 的
            // 但时间上 0.3 秒就到底部了,剩余的 0.7 在 0.01 到 0 这个层次变化。
            // 所以才会发明差值器这种东西把。
            startTransition(300);
        } else {
            resetTransition();
        }
        return true;
    }

    private boolean isStatePressed(int[] states) {
        for (int s : states) {
            if (s == android.R.attr.state_pressed) {
                return true;
            }
        }
        return false;
    }

}
public class FlatButton extends TextView {

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

    public FlatButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        int cornerRadius = dp2px(context, 6);
        
        ColorDrawable originalBackground = (ColorDrawable) getBackground();
        if (originalBackground != null) {
            GradientDrawable unpressed = new GradientDrawable();
            unpressed.setCornerRadius(cornerRadius);
            int bgColor = originalBackground.getColor();
            unpressed.setColor(bgColor);

            GradientDrawable pressed = new GradientDrawable();
            pressed.setCornerRadius(cornerRadius);
            int bgColorPressed = colorBurn(bgColor);
            pressed.setColor(bgColorPressed);

            Drawable[] d = new Drawable[]{pressed, unpressed};
            BottomInsetTransitionDrawable background = new BottomInsetTransitionDrawable(d, 12);
            setBackground(background);
            setTextColor(Color.WHITE);
            setClickable(true);
        }
    }

    //

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

    /**
     * 颜色加深处理
     *
     * @param RGBValues RGB的值,由alpha(透明度)、red(红)、green(绿)、blue(蓝)构成,
     *                  Android中我们一般使用它的16进制,
     *                  例如:"#FFAABBCC",最左边到最右每两个字母就是代表alpha(透明度)、
     *                  red(红)、green(绿)、blue(蓝)。每种颜色值占一个字节(8位),值域0~255
     *                  所以下面使用移位的方法可以得到每种颜色的值,然后每种颜色值减小一下,在合成RGB颜色,颜色就会看起来深一些了
     * @return
     */
    private int colorBurn(int RGBValues) {
        //int alpha = RGBValues >> 24;
        int red = RGBValues >> 16 & 0xFF;
        int green = RGBValues >> 8 & 0xFF;
        int blue = RGBValues & 0xFF;
        red = (int) Math.floor(red * (1 - 0.2));
        green = (int) Math.floor(green * (1 - 0.2));
        blue = (int) Math.floor(blue * (1 - 0.2));
        return Color.rgb(red, green, blue);
    }

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值