Android自定义View新年烟花、祝福语横幅动画
作者:匆忙拥挤repeat 时间:2022-01-24 21:31:27
新年了,项目中要作个动画,整体要求实现彩带乱飞,烟花冲天而起,烟花缩放,小鸡换图,小鸡飘移,横幅裁剪、展开等动画效果,全局大量使用了属性动画来实现。
如下效果图:
我在实现过程中,横幅的裁剪计算,捣腾了比较久的时间,初版采用属性动画计算float的一个比率值,来配合每一帧的裁剪绘制,如下代码:
private static class RollView extends View {
private Bitmap mBitmap;
private Rect mSrc;
private Rect mDst;
private int mRollWidth = 60;
private float mRate;
private boolean mIsStopAnim;
public RollView(Context context) {
super(context);
mSrc = new Rect();
mDst = new Rect();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap == null) return;
drawFromMiddleByFloatCompute(canvas);
}
private void drawFromMiddleByFloatCompute(Canvas canvas) {
/*
以下src 都需要加上mBitmap. 的前缀,, 因从drawable拿到的是原始图片宽高
而适配时,可能view的宽高比 drawable的宽高还小或大
*/
final float rate = mRate;
mSrc.left = 0;
mSrc.top = 0;
mSrc.right = mRollWidth;
mSrc.bottom = mBitmap.getHeight();
mDst.left = (int) ((getWidth() / 2 - mRollWidth) - (getWidth() / 2 - mRollWidth) * rate);
mDst.top = 0;
mDst.right = mDst.left + mRollWidth + 1;//因精度问题,这里强制+1
mDst.bottom = getHeight();
canvas.drawBitmap(mBitmap, mSrc, mDst, null);
//中间
int sw = (int) ((mBitmap.getWidth() - mRollWidth * 2) * rate);
mSrc.left = mBitmap.getWidth() / 2 - sw / 2;
mSrc.top = 0;
mSrc.right = mSrc.left + sw;
mSrc.bottom = mBitmap.getHeight();
int dw = (int) ((getWidth() - mRollWidth * 2) * rate);
mDst.left = getWidth() / 2 - dw / 2;
mDst.top = 0;
mDst.right = mDst.left + dw;
mDst.bottom = getHeight();
canvas.drawBitmap(mBitmap, mSrc, mDst, null);
//右边
mSrc.left = mBitmap.getWidth() - mRollWidth;
mSrc.top = 0;
mSrc.right = mBitmap.getWidth();
mSrc.bottom = mBitmap.getHeight();
mDst.left = (int) (getWidth() / 2 + (getWidth() / 2 - mRollWidth) * rate);
mDst.top = 0;
mDst.right = mDst.left + mRollWidth;
mDst.bottom = getHeight();
canvas.drawBitmap(mBitmap, mSrc, mDst, null);
}
public void setRes(int resId) {
mBitmap = getBitmapFromLocal(resId);
}
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
public void startFloatComputeAnim() {
/*
如果有float获取比率值,从而计算出相应的坐标值,那么可能由于最终在转成Rect的坐标时,
float to int ,有精度的损失:1个px 而引起效果的不理想
*/
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (mIsStopAnim) {
animation.cancel();
return;
}
mRate = (float) animation.getAnimatedValue();
invalidate();
}
});
animator.setDuration(2000);
animator.start();
}
public void stopAnim() {
mIsStopAnim = true;
}
}
> 因float转int有一个精度损失的问题,所以在计算中强制加上了1px(代码中有);
这样虽然解决了有1px没有绘制的问题,但是会发生绘制时不够平滑,而出现抖动的情形(在某些devices上)
所以最好还是不要使用float来计算
> 后来,同事猜想使用一个固定int值 来参与计算,可能可以解决上述问题:
比如每秒30帧,这里动画时长2秒,即共30*2=60帧;
图片宽度、左画轴、右画轴 对 60帧数 做相应的除法及其他计算,可得出一个单帧中 它们应该运动的x距离
> 之后,我又想了一种,使用一个属性动画,来计算出从0到getWidth()之间的 动画值,
从而通过计算,使得横幅从左向右拉开, 如下:
代码就不整体开源了
来源:http://blog.csdn.net/jjwwmlp456/article/details/54669827
标签:Android,新年烟花,横幅
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Mybatis延迟加载的实现方式
2023-08-19 11:07:32
![](https://img.aspxhome.com/file/2023/8/67018_0s.png)
分享我在工作中遇到的多线程下导致RCW无法释放的问题
2022-10-14 21:07:29
可空类型Nullable<T>用法详解
2023-01-19 19:54:28
java编码IDEA主题推荐
2021-10-21 03:54:18
![](https://img.aspxhome.com/file/2023/6/85506_0s.jpg)
Android调用系统的发邮件功能的小例子
2022-09-09 04:23:11
Jackson库中objectMapper的用法
2023-10-25 13:20:40
![](https://img.aspxhome.com/file/2023/4/104064_0s.jpg)
springboot如何实现自动装配源码解读
2023-11-10 15:44:20
(starters)springboot-starter整合阿里云datahub方式
2023-03-12 06:28:16
![](https://img.aspxhome.com/file/2023/3/86813_0s.png)
C#中使用UDP通信的示例
2022-11-19 21:09:07
![](https://img.aspxhome.com/file/2023/0/106520_0s.png)
详解Flutter中视频播放器插件的使用教程
2023-06-15 23:47:31
![](https://img.aspxhome.com/file/2023/9/83519_0s.jpg)
详解idea从git上拉取maven项目详细步骤
2023-04-23 08:51:56
![](https://img.aspxhome.com/file/2023/5/83115_0s.png)
Java中实现线程间通信的实例教程
2021-10-12 17:33:30
![](https://img.aspxhome.com/file/2023/2/84292_0s.png)
基于Retrofit2+RxJava2实现Android App自动更新
2021-09-04 20:19:29
![](https://img.aspxhome.com/file/2023/4/137214_0s.png)
SpringBoot常用数据库开发技术汇总介绍
2023-11-11 09:39:22
C#微信开发之微信公众号标签管理功能
2023-04-17 20:20:44
![](https://img.aspxhome.com/file/2023/1/100171_0s.png)
springboot2.0如何通过fastdfs实现文件分布式上传
2022-03-20 16:49:24
![](https://img.aspxhome.com/file/2023/7/71917_0s.png)
基于c# Task自己动手写个异步IO函数
2021-08-06 12:07:56
![](https://img.aspxhome.com/file/2023/4/108664_0s.png)
java中Object类4种方法详细介绍
2023-11-03 16:06:12
![](https://img.aspxhome.com/file/2023/4/58824_0s.jpg)
c# 如何实现自动更新程序
2021-11-20 21:02:41
![](https://img.aspxhome.com/file/2023/2/85662_0s.png)
Android使用GPS获取用户地理位置并监听位置变化的方法
2022-03-29 14:24:17
![](https://img.aspxhome.com/file/2023/8/92628_0s.png)