Android自定义View新年烟花、祝福语横幅动画

作者:匆忙拥挤repeat 时间:2022-01-24 21:31:27 

新年了,项目中要作个动画,整体要求实现彩带乱飞,烟花冲天而起,烟花缩放,小鸡换图,小鸡飘移,横幅裁剪、展开等动画效果,全局大量使用了属性动画来实现。

如下效果图:

Android自定义View新年烟花、祝福语横幅动画

我在实现过程中,横幅的裁剪计算,捣腾了比较久的时间,初版采用属性动画计算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()之间的 动画值,
从而通过计算,使得横幅从左向右拉开, 如下:

Android自定义View新年烟花、祝福语横幅动画

代码就不整体开源了

来源:http://blog.csdn.net/jjwwmlp456/article/details/54669827

标签:Android,新年烟花,横幅
0
投稿

猜你喜欢

  • 如何在C#中使用指针

    2022-07-02 16:09:47
  • 解决spring cloud服务启动之后回到命令行会自动挂掉问题

    2022-09-29 13:16:29
  • C语言常用占位符的使用小结

    2023-06-10 01:00:04
  • Spring boot使用多线程过程步骤解析

    2023-04-03 04:54:50
  • C#实现字体旋转的方法

    2023-01-19 06:41:40
  • SpringCloud之@FeignClient()注解的使用方式

    2022-05-16 04:22:40
  • 使用注解@Validated和BindingResult对入参进行非空校验方式

    2022-09-16 11:30:44
  • java swing GUI窗口美化方式

    2023-04-03 00:13:56
  • C#对Xamarin框架进行数据绑定

    2022-04-07 23:36:50
  • 无法从 int? 转换为 int 运行时出现错误

    2022-01-02 08:26:11
  • Android Shader应用开发之霓虹闪烁文字效果

    2022-09-11 16:43:20
  • Java方法的返回值及注意事项小结

    2022-10-02 16:55:28
  • Spring+MyBatis实现数据读写分离的实例代码

    2021-08-31 04:34:48
  • 详解从零开始---用C#制作扫雷游戏

    2022-06-14 13:33:12
  • C#实现让窗体永远在窗体最前面显示的实例

    2022-09-25 21:40:17
  • Android结束进程的方法详解

    2023-06-09 20:27:30
  • java 8如何自定义收集器(collector)详解

    2022-02-12 07:22:17
  • 半小时实现Java手撸网络爬虫框架(附完整源码)

    2022-11-23 15:59:35
  • SpringBoot+hutool实现图片验证码

    2021-06-17 02:55:27
  • Android中的Intent Filter匹配规则简介

    2021-07-29 16:02:30
  • asp之家 软件编程 m.aspxhome.com