会闪光的按钮Button和图片ImageView,ProgressBar进度条颜色闪动

模仿发光文字做了个会发光的按钮,效果如下

这里写图片描述

原理很简单,就是在view的基础上画一道白色渐变表示亮光,移动亮光位置形成闪光动画

下面贴代码

public class ShanView extends TextView {
    // private LinearGradient mLinearGradient;
    private Shader mGradient;
    private Matrix mGradientMatrix;
    private Paint mPaint;
    private int mViewWidth = 0, mViewHeight = 0;
    ;
    private float mTranslateX = 0, mTranslateY = 0;

    private boolean mAnimating = false;

    public ShanView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public ShanView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ShanView(Context context) {
        super(context);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int w = getMeasuredWidth();
        int h = getMeasuredHeight();
        rect = new Rect(0, 0, w, h);
    }

    private Rect rect;

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mViewWidth == 0) {
            mViewWidth = getMeasuredWidth();
            mViewHeight = getMeasuredHeight();
            if (mViewWidth > 0) {
                mPaint = new Paint();
                //亮光闪过
                mGradient = new LinearGradient(0, 0, mViewWidth, mViewHeight, new int[]{0x00ffffff, 0x55ffffff,
                        0x00ffffff}, new float[]{0, 0.9f, 1}, Shader.TileMode.CLAMP);
                //暗色
                //  mGradient = new LinearGradient(0, 0, mViewWidth, mViewHeight, new int[]{0x00000000, 0x55000000,
                //  0x00000000}, new float[]{0, 0.9f, 1}, Shader.TileMode.CLAMP);
                //用暗色凸显亮亮光(不好用)
                // mGradient = new LinearGradient(0, 0, mViewWidth, mViewHeight, new int[]{0x33000000, 0x00000000, 0x00ffffff, 0x88ffffff,
                //0x00ffffff, 0x00000000, 0x33000000}, new float[]{0, 0.3f, 0.3f, 0.58f, 0.7f, 0.7f, 1}, Shader.TileMode.CLAMP);
                mPaint.setShader(mGradient);
                mPaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
                mGradientMatrix = new Matrix();
                mGradientMatrix.setTranslate(-2 * mViewWidth, mViewHeight);
                mGradient.setLocalMatrix(mGradientMatrix);
                rect = new Rect(0, 0, w, h);
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mAnimating && mGradientMatrix != null) {
            canvas.drawRect(rect, mPaint);
        }
    }

    private ValueAnimator valueAnimator;

    private void init() {
        initValueAnimator();
    }

    private void initValueAnimator() {
        valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(6000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float v = (Float) animation.getAnimatedValue();
                mTranslateX = 4 * mViewWidth * v - mViewWidth * 2;
                mTranslateY = mViewHeight * v;
                mGradientMatrix.setTranslate(mTranslateX, mTranslateY);
                mGradient.setLocalMatrix(mGradientMatrix);
                invalidate();
            }
        });
        if (autoRun)
        getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                mAnimating = true;
                valueAnimator.start();
            }
        });
    }
    //是否自动运行动画
     private boolean autoRun = true;

    public void setAutoRun(boolean autoRun) {
        this.autoRun = autoRun;
    }
    //停止动画
    public void pause() {
        if (mAnimating) {
            mAnimating = false;
            valueAnimator.cancel();
            invalidate();
        }
    }
    //重新开始动画
    public void resume() {
        if (!mAnimating) {
            mAnimating = true;
            valueAnimator = ValueAnimator.ofFloat(0, 1);
            valueAnimator.setDuration(6000);
            valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
            valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float v = (Float) animation.getAnimatedValue();
                    mTranslateX = 4 * mViewWidth * v - mViewWidth * 2;
                    mTranslateY = mViewHeight * v;
                    mGradientMatrix.setTranslate(mTranslateX, mTranslateY);
                    mGradient.setLocalMatrix(mGradientMatrix);
                    invalidate();
                }
            });
            valueAnimator.start();
        }
    }
}

可以改为继承其他View比如ImageView

可以用在ProgressBar上,只绘制有进度部分的颜色闪光.

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(0x00ffffff);
        int saveCount = canvas.saveLayer(rect, mPaint, Canvas.ALL_SAVE_FLAG);
        if (mAnimating && mGradientMatrix != null) {
            rect.right = mProgresWidth = (float) getProgress() / getMax() * mViewWidth;
            canvas.drawRect(rect, mPaint);
        }
        canvas.restoreToCount(saveCount);
    }

换用了黑色的渐变

 //暗色
 mGradient=new LinearGradient(0, 0, 0, mViewHeight, new int[]0x00000000, 0x55000000,
                        0x00000000}, new float[]{0, 0.9f, 1}, Shader.TileMode.CLAMP);

改进度条风格的办法,在drawble下新建一个xml文件,设置为该进度条的progressDrawable
一级和二级进度条的clip一定要有,否则进度条就像背景一样全部显示了

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 设置背景色图像资源 -->
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="10dp" />

            <solid android:color="#ffeeeeee" />
        </shape>
    </item>
    <!-- 设置第二级进度条颜色图像资源 -->
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="10dp" />

                <solid android:color="#880000ff" />
            </shape>
        </clip>
    </item>
    <!-- 设置第一级进度条颜色图像资源 -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="10dp" />

                <solid android:color="#880000ff" />
            </shape>
        </clip>
    </item>

</layer-list>

进度条本身的进度动画就省略不提了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值