FlatButton

来源:互联网 发布:曼哈顿软件 招聘 编辑:程序博客网 时间:2024/06/14 18:18


关键就是实现平滑地改变上层 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);    }}





0 0