Android繁星眨眼动画效果

分享一个类似星星眨眼的动画效果实现方式。这里涉及到两个类,看官可直接拿来用。

StarView.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.Random;

public class StarView extends View {
    private Paint mPaint;
    private Bitmap mStarOn;
    private Bitmap mStarOff;
    private int mStarsNumber=10;
    private ArrayList<StarModel> mStarModelList = null;
    private int mCenterX, mCenterY;
    private boolean mAnimatorStatus=true;
    private Random mRandom;

    public StarView(Context context) {
        this(context, null);
    }

    public StarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mStarOn = getBitmapFromDrawable(getContext(),android.R.drawable.star_on);
        mStarOff = getBitmapFromDrawable(getContext(), android.R.drawable.star_off);
    }

    private Bitmap getBitmapFromDrawable(Context context, int drawableId) {
        Drawable drawable = ContextCompat.getDrawable(context, drawableId);
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof VectorDrawable) {
            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        }

        return null;
    }

    /**
     * 设置星星图片
     * @param starOn
     * @param starOff
     */
    public void setStar(int starOn,int starOff){
        mStarOn=getBitmapFromDrawable(getContext(),starOn);
        mStarOff=getBitmapFromDrawable(getContext(),starOff);
    }

    /**
     * 设置星星数量
     * @param number 参数值范围(1-100)
     * @return 0:设置成功 -1:设置失败
     */
    public int setStarsNumber(int number){
        if(number<=0||number>100){
            return -1;
        }
        mStarsNumber=number;
        return 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mCenterX = getMeasuredWidth() / 2 - mStarOn.getWidth() / 2; // 90
        mCenterY = getMeasuredHeight() / 2 - mStarOn.getHeight() / 2; // 90
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i("StarView", "onDraw");
        if (mStarModelList == null) {
            return;
        }
        calculate(canvas);
    }
    //在这个方法里会随机地去改变星星的位置和图片类型,以达到眨眼效果
    protected void calculate(Canvas canvas){
        if(mRandom==null){
            mRandom= new Random();
        }
        float angle = 0;
        int i=0;
        float startX=0,startY=0;
        for (StarModel starModel : mStarModelList) {
            i++;
            if (i == 0) {
                angle = (float) ((10 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } else if (i == 1) {
                angle = (float) ((30 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(2) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } else if (i == 2) {
                angle = (float) ((40 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.25f;
                startY = (float) Math.sin(angle) * mCenterY * 0.4f;
            } else if (i == 3) {
                angle = (float) ((60 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.13f;
                startY = (float) Math.sin(angle) * mCenterY * 0.33f;
            } else if (i == 4) {
                angle = (float) ((50) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.16f;
                startY = (float) Math.sin(angle) * mCenterY * 0.17f;
            } else if (i == 5) {
                angle = (float) ((80) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.05f;
                startY = (float) Math.sin(angle) * mCenterY * 0.3f;
            } else if (i == 6) {
                angle = (float) ((145) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.15f;
                startY = (float) Math.sin(angle) * mCenterY * 0.28f;
            } else if (i == 7) {
                angle = (float) ((205) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.15f;
                startY = (float) Math.sin(angle) * mCenterY * 0.15f;
            } else if (i == 8) {
                angle = (float) ((215) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } else if (i == 9) {
                angle = (float) ((225) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.14f;
                startY = (float) Math.sin(angle) * mCenterY * 0.15f;
            }else {
                angle = (float) ((215) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            }
            starModel.setmStartX(startX);
            starModel.setmStartY(startY);
            if (mRandom.nextInt(12) % 2 == 0) {
                starModel.setmIcon(mStarOn);
            } else {
                starModel.setmIcon(mStarOff);
            }
            starModel.draw(canvas, mPaint, mCenterX, mCenterY);
        }
    }

    /**
     * 开始动画
     * @return
     */
    public void startAnimation() {
        mAnimatorStatus=true;
        initStarModel();
        //这里开启一个线程,不断地去刷新view(调用invalidate方法后调用onDraw)
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (mAnimatorStatus){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    invalidate();
                }
            }
        }.start();
    }

    /**
     * 停止动画
     */
    public void stopAnimation() {
        mAnimatorStatus=false;
    }

    private void initStarModel() {
        Log.i("StarView","initStarModel");
        if(mStarModelList==null){
            mStarModelList = new ArrayList<>(mStarsNumber);
        }else {
            mStarModelList.clear();
        }
        Bitmap bitmap = mStarOn;
        for (int i = 0; i < mStarsNumber; i++) {
            Matrix matrix = new Matrix();
            StarModel model = new StarModel(bitmap, 0, 0, matrix);
            mStarModelList.add(model);
        }
    }
}

StarModel.java

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.Log;

public class StarModel {
    private Bitmap mIcon;// 图片
    private float mStartX;// 起始位置
    private float mStartY;// 起始位置
    private Matrix mMatrix;// 矩阵

    public StarModel(Bitmap mIcon, float mStartX, float mStartY, Matrix matrix) {
        this.mIcon = mIcon;
        this.mStartX = mStartX;
        this.mStartY = mStartY;
        this.mMatrix = matrix;
    }

    public void draw(Canvas canvas, Paint paint, int centerX, int centerY) {
        float left = centerX + mStartX;
        float top = centerY + mStartY;
        Log.i("StarModel","centerY: "+centerY+" mStartY: "+mStartY);
        Log.i("StarModel","left: "+left+" top: "+top);
        mMatrix.setTranslate(left, top);
        canvas.drawBitmap(mIcon, mMatrix, paint);
    }

    public Bitmap getmIcon() {
        return mIcon;
    }

    public void setmIcon(Bitmap mIcon) {
        this.mIcon = mIcon;
    }

    public float getmStartX() {
        return mStartX;
    }

    public void setmStartX(float mStartX) {
        this.mStartX = mStartX;
    }

    public float getmStartY() {
        return mStartY;
    }

    public void setmStartY(float mStartY) {
        this.mStartY = mStartY;
    }

    public Matrix getmMatrix() {
        return mMatrix;
    }

    public void setmMatrix(Matrix mMatrix) {
        this.mMatrix = mMatrix;
    }

}

使用方法:

1,在布局文件里面加入StarView

<com.xxx.xxx.xxx.StarView
            android:id="@+id/star"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

2,在Activity里调用

final StarView starView = findViewById(R.id.star);
starView.setStar(R.drawable.star,R.drawable.star2);
.....
start_annmotion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                starView.startAnimation();
            }
});
findViewById(R.id.stop_annmotion).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                starView.stopAnimation();
            }
});

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值