Android下红包雨的实现
生活随笔
收集整理的這篇文章主要介紹了
Android下红包雨的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近做項目的時候,需要做一個類似下紅包雨的效果。經過自己的反復研究,發現使用動畫是最合適的。下面貼出這種實現效果的流程
首先看一下紅包雨的簡單效果圖
(1)view初始化
(2)view的繪制
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//獲取自定義view的寬度mWidth = getMeasuredWidth();}@Overrideprotected void onDraw(final Canvas canvas) {//遍歷紅包數組,繪制紅包for (int i = 0; i < redpacketlist.size(); i++) {RedPacket redPacket = redpacketlist.get(i);//將紅包旋轉redPacket.rotation角度后 移動到(redPacket.x,redPacket.y)進行繪制紅包Matrix m = new Matrix();m.setTranslate(-redPacket.width / 2, -redPacket.height / 2);m.postRotate(redPacket.rotation);m.postTranslate(redPacket.width / 2 + redPacket.x, redPacket.height / 2 + redPacket.y);//繪制紅包canvas.drawBitmap(redPacket.bitmap, m, paint);}}(3)設置紅包雨的開始結束等事件
/***停止動畫*/public void stopRainNow() {//清空紅包數據clear();//重繪invalidate();//動畫取消animator.cancel();}/*** 開始動畫*/public void startRain() {//清空紅包數據clear();//添加紅包setRedpacketCount(count);prevTime = System.currentTimeMillis();//動畫開始animator.start();}public void setRedpacketCount(int count) {if (mImgIds == null || mImgIds.length == 0)return;for (int i = 0; i < count; ++i) {//獲取紅包原始圖片Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), mImgIds[0]);//生成紅包實體類RedPacket redPacket = new RedPacket(getContext(), originalBitmap, speed,maxSize,minSize,mWidth);//添加進入紅包數組redpacketlist.add(redPacket);}}/*** 暫停紅包雨*/public void pauseRain() {animator.cancel();}/*** 重新開始*/public void restartRain() {animator.start();}/*** 清空紅包數據,并回收紅包中的bitmap*/private void clear() {for (RedPacket redPacket :redpacketlist) {redPacket.recycle();}redpacketlist.clear();}(4)設置紅包雨的點擊事件
@Overridepublic boolean onTouchEvent(MotionEvent motionEvent) {switch (motionEvent.getAction()){case MotionEvent.ACTION_DOWN://根據點擊的坐標點,判斷是否點擊在紅包的區域RedPacket redPacket = isRedPacketClick(motionEvent.getX(), motionEvent.getY());if (redPacket != null) {//如果點擊在紅包上,重新設置起始位置,以及中獎屬性redPacket.y = 0 - redPacket.height;redPacket.isRealRed = redPacket.isRealRedPacket();if (onRedPacketClickListener != null) {onRedPacketClickListener.onRedPacketClickListener(redPacket);}}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:break;}return true;}//根據點擊坐標點,遍歷紅包數組,看是否點擊在紅包上private RedPacket isRedPacketClick(float x, float y) {for (int i = redpacketlist.size() - 1; i >= 0; i --) {if (redpacketlist.get(i).isContains(x, y)) {return redpacketlist.get(i);}}return null;}最后貼出紅包雨的完整代碼
public class RedPacketTest extends View {private int[] mImgIds = new int[]{R.drawable.red_packets_icon};//紅包圖片private int count;//紅包數量private int speed;//下落速度private float maxSize;//紅包大小的范圍private float minSize;//紅包大小的范圍private int mWidth;//view寬度private ValueAnimator animator;//屬性動畫,用該動畫來不斷改變紅包下落的坐標值private Paint paint;//畫筆private long prevTime;private ArrayList<RedPacket> redpacketlist = new ArrayList<>();//紅包數組public RedPacketTest(Context context) {super(context);init();}public RedPacketTest(Context context, @Nullable AttributeSet attrs) {super(context, attrs);final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RedPacketStyle);count = typedArray.getInt(R.styleable.RedPacketStyle_count, 20);speed = typedArray.getInt(R.styleable.RedPacketStyle_speed, 20);minSize = typedArray.getFloat(R.styleable.RedPacketStyle_min_size, 0.5f);maxSize = typedArray.getFloat(R.styleable.RedPacketStyle_max_size, 1.2f);typedArray.recycle();init();}/*** 初始化*/private void init() {paint = new Paint();paint.setFilterBitmap(true);paint.setDither(true);paint.setAntiAlias(true);animator = ValueAnimator.ofFloat(0, 1);setLayerType(View.LAYER_TYPE_HARDWARE, null);initAnimator();}private void initAnimator() {//每次動畫更新的時候,更新紅包下落的坐標值animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {long nowTime = System.currentTimeMillis();float secs = (float) (nowTime - prevTime) / 1000f;prevTime = nowTime;for (int i = 0; i < redpacketlist.size(); ++i) {RedPacket redPacket = redpacketlist.get(i);//更新紅包的下落的位置yredPacket.y += (redPacket.speed * secs);//如果y坐標大于view的高度 說明劃出屏幕,y重新設置起始位置,以及中獎屬性if (redPacket.y > getHeight()) {redPacket.y = 0 - redPacket.height;redPacket.isRealRed = redPacket.isRealRedPacket();}//更新紅包的旋轉的角度redPacket.rotation = redPacket.rotation+ (redPacket.rotationSpeed * secs);}invalidate();}});//屬性動畫無限循環animator.setRepeatCount(ValueAnimator.INFINITE);//屬性值線性變換animator.setInterpolator(new LinearInterpolator());animator.setDuration(0);}/***停止動畫*/public void stopRainNow() {//清空紅包數據clear();//重繪invalidate();//動畫取消animator.cancel();}/*** 開始動畫*/public void startRain() {//清空紅包數據clear();//添加紅包setRedpacketCount(count);prevTime = System.currentTimeMillis();//動畫開始animator.start();}public void setRedpacketCount(int count) {if (mImgIds == null || mImgIds.length == 0)return;for (int i = 0; i < count; ++i) {//獲取紅包原始圖片Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), mImgIds[0]);//生成紅包實體類RedPacket redPacket = new RedPacket(getContext(), originalBitmap, speed,maxSize,minSize,mWidth);//添加進入紅包數組redpacketlist.add(redPacket);}}/*** 暫停紅包雨*/public void pauseRain() {animator.cancel();}/*** 重新開始*/public void restartRain() {animator.start();}/*** 清空紅包數據,并回收紅包中的bitmap*/private void clear() {for (RedPacket redPacket :redpacketlist) {redPacket.recycle();}redpacketlist.clear();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//獲取自定義view的寬度mWidth = getMeasuredWidth();}@Overrideprotected void onDraw(final Canvas canvas) {//遍歷紅包數組,繪制紅包for (int i = 0; i < redpacketlist.size(); i++) {RedPacket redPacket = redpacketlist.get(i);//將紅包旋轉redPacket.rotation角度后 移動到(redPacket.x,redPacket.y)進行繪制紅包Matrix m = new Matrix();m.setTranslate(-redPacket.width / 2, -redPacket.height / 2);m.postRotate(redPacket.rotation);m.postTranslate(redPacket.width / 2 + redPacket.x, redPacket.height / 2 + redPacket.y);//繪制紅包canvas.drawBitmap(redPacket.bitmap, m, paint);}}@Overridepublic boolean onTouchEvent(MotionEvent motionEvent) {switch (motionEvent.getAction()){case MotionEvent.ACTION_DOWN://根據點擊的坐標點,判斷是否點擊在紅包的區域RedPacket redPacket = isRedPacketClick(motionEvent.getX(), motionEvent.getY());if (redPacket != null) {//如果點擊在紅包上,重新設置起始位置,以及中獎屬性redPacket.y = 0 - redPacket.height;redPacket.isRealRed = redPacket.isRealRedPacket();if (onRedPacketClickListener != null) {onRedPacketClickListener.onRedPacketClickListener(redPacket);}}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:break;}return true;}//根據點擊坐標點,遍歷紅包數組,看是否點擊在紅包上private RedPacket isRedPacketClick(float x, float y) {for (int i = redpacketlist.size() - 1; i >= 0; i --) {if (redpacketlist.get(i).isContains(x, y)) {return redpacketlist.get(i);}}return null;}public interface OnRedPacketClickListener {void onRedPacketClickListener(RedPacket redPacket);}private OnRedPacketClickListener onRedPacketClickListener;public void setOnRedPacketClickListener(OnRedPacketClickListener onRedPacketClickListener) {this.onRedPacketClickListener = onRedPacketClickListener;} }總結
以上是生活随笔為你收集整理的Android下红包雨的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我认识的乔布斯
- 下一篇: android sina oauth2.