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()之间的 动画值,
从而通过计算,使得横幅从左向右拉开, 如下:

代码就不整体开源了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 非常漂亮的新年祝福!C语言实现漂亮的烟花效果

    本文实例为大家分享了C语言实现漂亮的烟花效果展示的具体代码,供大家参考,具体内容如下 程序名称:祝福烟花,祝福朋友 编译环境:VC++6.0 && easyx(立冬版) #include <graphics.h> #include <conio.h> #include <iostream.h> #include <math.h> #include <time.h> #include <stdio.h> #include

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

    新年了,项目中要作个动画,整体要求实现彩带乱飞,烟花冲天而起,烟花缩放,小鸡换图,小鸡飘移,横幅裁剪.展开等动画效果,全局大量使用了属性动画来实现. 如下效果图: 我在实现过程中,横幅的裁剪计算,捣腾了比较久的时间,初版采用属性动画计算float的一个比率值,来配合每一帧的裁剪绘制,如下代码: private static class RollView extends View { private Bitmap mBitmap; private Rect mSrc; private Rect m

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的错位感,代码很简单: import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.MotionEvent import android.vi

  • Android自定义view实现雪花特效实例代码

    目录 一.前言 二.创意名 三.效果展示 四.实现步骤 五.编码实现 总结 一.前言 这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效. 圣诞祝福:平安夜,舞翩阡.雪花飘,飞满天.心与心,永相伴. 圣诞节是传统的宗教节日,对于基 督徒,那是庆祝耶稣的诞生,纪念耶稣和发扬基督精神.现在整个西方社会都在过圣诞节,像许多宗教节日一样,它已经越来越民俗化了. 尽管如此,圣诞节依然倍受尊重.人们在圣诞快乐中怀有对耶稣的敬仰,欢乐的节庆里含有庄严肃穆的神念.欢度圣诞佳节的人都不拒绝耶稣的教

  • Android 自定义View 密码框实例代码

    暴露您view中所有影响可见外观的属性或者行为. •通过XML添加和设置样式 •通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 效果图展示: 支持的样式 可以通过XML定义影响外边和行为的属性如下 边框圆角值,边框颜色,分割线颜色,边框宽度,密码长度,密码大小,密码颜色 <declare-styleable name="PasswordInputView"> <attr name="borde

  • Android自定义View详解

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 我把3用[]标出了,所以说3不一

  • Android自定义View中attrs.xml的实例详解

    Android自定义View中attrs.xml的实例详解 我们在自定义View的时候通常需要先完成attrs.xml文件 在values中定义一个attrs.xml 然后添加相关属性 这一篇先详细介绍一下attrs.xml的属性. <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定义公共属性 <attr name="titleText" for

  • Android自定义View 仿QQ侧滑菜单的实现代码

    先看看QQ的侧滑效果 分析一下 先上原理图(不知道能否表达的清楚 ==) -首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图 - 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果:然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列.原理搞清了实现起来

  • Android自定义View绘制随机生成图片验证码

    本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

  • Android自定义View绘制的方法及过程(二)

    上一篇<Android 自定义View(一) Paint.Rect.Canvas介绍>讲了最基础的如何自定义一个View,以及View用到的一些工具类.下面讲下View绘制的方法及过程 public class MyView extends View { private String TAG = "--------MyView"; private int width, height; public MyView(Context context, AttributeSet a

随机推荐