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

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

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

新年了,项目中要作个动画,如下效果图:

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

我在实现过程中,横幅的裁剪计算,捣腾了比较久的时间,初版采用属性动画计算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,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,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仿QQ聊天撒花特效 很真实Android营造雪花和雨滴浪漫效果 总结

以上是内存溢出为你收集整理的Android自定义View新年烟花、祝福语横幅动画全部内容,希望文章能够帮你解决Android自定义View新年烟花、祝福语横幅动画所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143049.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存