1. 程式人生 > >會閃光的按鈕Button和圖片ImageView,ProgressBar進度條顏色閃動

會閃光的按鈕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>

進度條本身的進度動畫就省略不提了