实现点赞效果动画,可以根据需求进行修改使用。

先上个Gif图:

1.自定义DivergeView

import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PointF;import android.util.AttributeSet;import android.view.View;import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;import java.util.List;import java.util.Random;public class DivergeView extends View implements Runnable {    public static final float mDuration = 0.01F;    public static final int mDefaultHeight = 100;    protected static final long mQueenDuration = 200L;    protected final Random mRandom;    protected ArrayList mDivergeInfos;    protected List mQueen;    protected PointF mPtStart;    protected PointF mPtEnd;    protected ArrayList mDeadPool;    private Paint mPaint;    private DivergeViewProvider mDivergeViewProvider;    private long mLastAddTime;    private Thread mThread;    private boolean mRunning;    private boolean mIsDrawing;    public DivergeView(Context context) {        this(context, (AttributeSet) null);    }    public DivergeView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public DivergeView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.mRandom = new Random();        this.mDeadPool = new ArrayList();        this.mLastAddTime = 0L;        this.mRunning = true;        this.mIsDrawing = false;        this.init();    }    public void run() {        while (this.mRunning) {            if (this.mDivergeViewProvider != null && this.mQueen != null && !this.mIsDrawing && this.mDivergeInfos != null) {                this.dealQueen();                if (this.mDivergeInfos.size() != 0) {                    this.dealDiverge();                    this.mIsDrawing = true;                    this.postInvalidate();                }            }        }        this.release();    }    private void dealDiverge() {        for (int i = 0; i < this.mDivergeInfos.size(); ++i) {            DivergeInfo divergeInfo = (DivergeInfo) this.mDivergeInfos.get(i);            float timeLeft = 1.0F - divergeInfo.mDuration;            divergeInfo.mDuration += 0.01F;            float time1 = timeLeft * timeLeft;            float time2 = 2.0F * timeLeft * divergeInfo.mDuration;            float time3 = divergeInfo.mDuration * divergeInfo.mDuration;            float x = time1 * this.mPtStart.x + time2 * divergeInfo.mBreakPoint.x + time3 * divergeInfo.mEndPoint.x;            divergeInfo.mX = x;            float y = time1 * this.mPtStart.y + time2 * divergeInfo.mBreakPoint.y + time3 * divergeInfo.mEndPoint.y;            divergeInfo.mY = y;            if (divergeInfo.mY <= divergeInfo.mEndPoint.y) {                this.mDivergeInfos.remove(i);                this.mDeadPool.add(divergeInfo);                --i;            }        }    }    private void dealQueen() {        long now = System.currentTimeMillis();        if (this.mQueen.size() > 0 && now - this.mLastAddTime > 200L) {            this.mLastAddTime = System.currentTimeMillis();            DivergeInfo divergeInfo = null;            if (this.mDeadPool.size() > 0) {                divergeInfo = (DivergeInfo) this.mDeadPool.get(0);                this.mDeadPool.remove(0);            }            if (divergeInfo == null) {                divergeInfo = this.createDivergeNode(this.mQueen.get(0));            }            divergeInfo.reset();            divergeInfo.mType = this.mQueen.get(0);            this.mDivergeInfos.add(divergeInfo);            this.mQueen.remove(0);        }    }    private void init() {        this.mPaint = new Paint(1);    }    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);    }    public void setDivergeViewProvider(DivergeViewProvider divergeViewProvider) {        this.mDivergeViewProvider = divergeViewProvider;    }    public PointF getStartPoint() {        return this.mPtStart;    }    public boolean isRunning() {        return this.mRunning;    }    public void startDiverges(Object obj) {        if (this.mDivergeInfos == null) {            this.mDivergeInfos = new ArrayList(30);        }        if (this.mQueen == null) {            this.mQueen = Collections.synchronizedList(new ArrayList(30));        }        this.mQueen.add(obj);        if (this.mThread == null) {            this.mThread = new Thread(this);            this.mThread.start();        }    }    public void stop() {        if (this.mDivergeInfos != null) {            this.mDivergeInfos.clear();        }        if (this.mQueen != null) {            this.mQueen.clear();        }        if (this.mDeadPool != null) {            this.mDeadPool.clear();        }    }    public void release() {        this.stop();        this.mPtEnd = null;        this.mPtStart = null;        this.mDivergeInfos = null;        this.mQueen = null;        this.mDeadPool = null;    }    public void setStartPoint(PointF point) {        this.mPtStart = point;    }    public void setEndPoint(PointF point) {        this.mPtEnd = point;    }    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        this.mRunning = false;    }    protected void onDraw(Canvas canvas) {        if (this.mRunning && this.mDivergeViewProvider != null && this.mDivergeInfos != null) {            Iterator var2 = this.mDivergeInfos.iterator();            while (var2.hasNext()) {                DivergeInfo divergeInfo = (DivergeInfo) var2.next();                this.mPaint.setAlpha((int) (255.0F * divergeInfo.mY / this.mPtStart.y));                canvas.drawBitmap(this.mDivergeViewProvider.getBitmap(divergeInfo.mType), divergeInfo.mX, divergeInfo.mY, this.mPaint);            }        }        this.mIsDrawing = false;    }    private PointF getBreakPointF(int scale1, int scale2) {        PointF pointF = new PointF();        pointF.x = (float) (this.mRandom.nextInt((this.getMeasuredWidth() - this.getPaddingRight() + this.getPaddingLeft()) / scale1) + this.getMeasuredWidth() / scale2);        pointF.y = (float) (this.mRandom.nextInt((this.getMeasuredHeight() - this.getPaddingBottom() + this.getPaddingTop()) / scale1) + this.getMeasuredHeight() / scale2);        return pointF;    }    protected DivergeInfo createDivergeNode(Object type) {        PointF endPoint = this.mPtEnd;        if (endPoint == null) {            endPoint = new PointF((float) this.mRandom.nextInt(this.getMeasuredWidth()), 0.0F);        }        if (this.mPtStart == null) {            this.mPtStart = new PointF((float) (this.getMeasuredWidth() / 2), (float) (this.getMeasuredHeight() - 100));        }        return new DivergeInfo(this.mPtStart.x, this.mPtStart.y, this.getBreakPointF(2, 3), endPoint, type);    }    public class DivergeInfo {        public float mDuration = 0.0F;        public PointF mBreakPoint;        public PointF mEndPoint;        public float mX;        public float mY;        public Object mType;        public float mStartX;        public float mStartY;        public DivergeInfo(float x, float y, PointF breakPoint, PointF endPoint, Object type) {            this.mEndPoint = endPoint;            this.mX = x;            this.mY = y;            this.mStartX = x;            this.mStartY = y;            this.mBreakPoint = breakPoint;            this.mType = type;        }        public void reset() {            this.mDuration = 0.0F;            this.mX = this.mStartX;            this.mY = this.mStartY;        }    }    public interface DivergeViewProvider {        Bitmap getBitmap(Object var1);    }}   

2.XML布局文件:

<?xml version="1.0" encoding="utf-8"?>        

3.在Activity中的代码:

public class MainActivity extends Activity {    private DivergeView mDivergeView;    private ImageView mImageView;    private ArrayList mList;    private int mIndex = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        initView();    }    //初始化布局    private void initView() {        mImageView = findViewById(R.id.iv_start);        mDivergeView = findViewById(R.id.divergeView);        mList = new ArrayList<>();        // 添加点赞图标        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm1, null)).getBitmap());        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm2, null)).getBitmap());        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm3, null)).getBitmap());        mList.add(((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.ic_praise_sm4, null)).getBitmap());        mImageView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (mIndex == mList.size()) {                    mIndex = 0;                }                mDivergeView.startDiverges(mIndex);                mIndex++;            }        });               mDivergeView.post(new Runnable() {            @Override            public void run() {                mDivergeView.setEndPoint(new PointF(mDivergeView.getMeasuredWidth() / 2, 0));                mDivergeView.setDivergeViewProvider(new Provider());            }        });    }    @Override    protected void onDestroy() {        super.onDestroy();        if (mList != null) {            mList.clear();            mList = null;        }    }    class Provider implements DivergeView.DivergeViewProvider {        @Override        public Bitmap getBitmap(Object obj) {            return mList == null ? null : mList.get((int) obj);        }    }}

 

更多相关文章

  1. 修改Android中Layout布局文件字体的大小
  2. 【Android】常用控件及布局
  3. Android 布局讲解
  4. Android 仿抖音上下滑动布局
  5. Android UI布局经验总结
  6. Android网格布局实现--GridView
  7. Android的xml布局文件代码讲解(TextView控件)

随机推荐

  1. Android底部菜单(Fragment控制切换多个页
  2. Kotlin 会被谷歌弃坑?看官方怎么说
  3. 如何Android数据库缓存进行管理
  4. Android笔记(十九)制作一个简易的指南针
  5. Android单元测试(一):JUnit框架的使用
  6. Android(安卓)Studio实现网络版音乐播放
  7. iOS和Android设计理念的演变
  8. androidRSA加密,java解密出现错误或者乱码
  9. Android设备的界面适配设计
  10. Android(安卓)高质量开发之崩溃优化