栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android实现炫酷播放效果

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android实现炫酷播放效果

本文实例为大家分享了Android实现播放效果的具体代码,供大家参考,具体内容如下

一、首先看效果

二、实现原理

使用贝塞尔曲线实现滑动效果,在使用属性动画实现水波纹效果,然后就能实现以上效果

三、实现

1、先封装动画框架,创建动画基础类

PathPoint.java

public class PathPoint {
 
  public static final int MOVE = 0;
  public static final int LINE = 1;
  public static final int CURVE = 2;
  float mControl0X, mControl0Y;
  float mControl1X, mControl1Y;
  public float mX, mY;
  int mOperation;
 
  //line/move
  private PathPoint(int operation, float x, float y) {
    this.mOperation = operation;
    this.mX = x;
    this.mY = y;
  }
 
  //curve
  private PathPoint(float c0X, float c0Y, float c1X, float c1Y, float x, float y) {
    this.mControl0X = c0X;
    this.mControl0Y = c0Y;
    this.mControl1X = c1X;
    this.mControl1Y = c1Y;
    this.mX = x;
    this.mY = y;
    this.mOperation = CURVE;
 
  }
 
  public static PathPoint moveTo(float x, float y) {
 
    return new PathPoint(MOVE, x, y);
 
  }
 
  public static PathPoint lineTo(float x, float y) {
 
    return new PathPoint(LINE, x, y);
 
  }
 
  public static PathPoint curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y) {
 
    return new PathPoint(c0X, c0Y, c1X, c1Y, x, y);
 
  }
}

2、创建动画集合类,并且保存绘制轨迹

AnimatorPath

public class AnimatorPath {
  //记录轨迹
  private List mPoints = new ArrayList<>();
 
  public void moveTo(float x, float y) {
    mPoints.add(PathPoint.moveTo(x, y));
  }
 
  public void lineTo(float x, float y) {
    mPoints.add(PathPoint.lineTo(x, y));
  }
 
  public void curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y) {
    mPoints.add(PathPoint.curveTo(c0X, c0Y, c1X, c1Y, x, y));
  }
 
 
  public Collection getPoints() {
    return mPoints;
  }
}

3、实现页面布局



 
 
  
 
  
 
    
 
      
      
    
  
 
  
 
    
 
      
 
      
 
      
 
    
 
    
  
 

4、获取控件,并且设置点击事件,设置一些动画常量

private View mFab;
  private frameLayout mFabcontainer;
  private LinearLayout mControlsContainer;
 
  //从什么时候开始执行动画
  private static final float SCALE_FACTOR = 13f;
  //持续时间
  private static final long ANIMATION_DURATION = 300;
  //贝塞尔曲线滑动到什么时候开始执行动画
  private static final float MINIMUN_X_DISTANCE = 200;
  private boolean mRevealFlag;
  private float mFabSize;

5、给mFab设置点击事件

private void onFabPressed(View view) {
    final float startX = mFab.getX();
    //开始动画
    AnimatorPath path = new AnimatorPath();
    path.moveTo(0, 0);
    path.curveTo(-200, 200, -400, 100, -600, 50);
//    path.lineTo(-600,50);
 
    ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc",
 new Pathevaluator(), path.getPoints().toArray());
    anim.setInterpolator(new AccelerateInterpolator());
//    anim.setRepeatCount(ValueAnimator.INFINITE);
//    anim.setRepeatMode(ValueAnimator.REVERSE);
    anim.setDuration(ANIMATION_DURATION);
    anim.start();
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator valueAnimator) {
 //到了path路径中的某个位置就是开始扩散动画
 if (Math.abs(startX - mFab.getX()) > MINIMUN_X_DISTANCE) {
   if (!mRevealFlag) {
     ImageButton fab = (ImageButton) mFab;
     fab.setImageDrawable(new BitmapDrawable());
     //看布局里边的FabContainer要比toolbar背景高mFabSize/2(为了最初的半个fab效果)
     mFabcontainer.setY(mFabcontainer.getY() + mFabSize / 2);
     //fab放大动画
     mFab.animate()
  .scaleXBy(SCALE_FACTOR)
  .scaleYBy(SCALE_FACTOR)
  .setListener(mEndRevealListener)
  .setDuration(ANIMATION_DURATION);
     mRevealFlag = true;
   }
 }
      }
    });
  }
 
  public void setFabLoc(PathPoint newLoc) {
    mFab.setTranslationX(newLoc.mX);
    if (mRevealFlag) {
      //因为布局里边的mFabcontainer要比toolbar背景高mFabSize/2,所以fab为了看起来平顺,需要上移mFabSize/2
      mFab.setTranslationY(newLoc.mY - (mFabSize / 2));
    } else {
      mFab.setTranslationY(newLoc.mY);
    }
 
  }
 
  private AnimatorListenerAdapter mEndRevealListener = new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
      super.onAnimationEnd(animation);
      mFab.setVisibility(View.INVISIBLE);
      mFabcontainer.setBackgroundColor(getResources().getColor(R.color.colorAccent));
      //reveal动画完毕后,接着每一个子控件都有个缩放动画(依次顺序出来)
      for (int i = 0; i < mControlsContainer.getChildCount(); i++) {
 View v = mControlsContainer.getChildAt(i);
 ViewPropertyAnimator animate = v.animate()
     .scaleX(1)
     .scaleY(1)
     .setDuration(ANIMATION_DURATION);
 animate.setStartDelay(i * 50);
 animate.start();
      }
    }
  };

Pathevaluator

public class Pathevaluator implements Typeevaluator {
  @Override
  public PathPoint evaluate(float t, PathPoint startValue, PathPoint endValue) {
    //t执行的百分比 (0~1)
    float x, y;
    if (endValue.mOperation == PathPoint.CURVE) {
      //三阶贝塞尔曲线 公式
      float oneMinusT = 1 - t;
      x = oneMinusT * oneMinusT * oneMinusT * startValue.mX +
   3 * oneMinusT * oneMinusT * t * endValue.mControl0X +
   3 * oneMinusT * t * t * endValue.mControl1X +
   t * t * t * endValue.mX;
      y = oneMinusT * oneMinusT * oneMinusT * startValue.mY +
   3 * oneMinusT * oneMinusT * t * endValue.mControl0Y +
   3 * oneMinusT * t * t * endValue.mControl1X +
   t * t * t * endValue.mY;
    } else if (endValue.mOperation == PathPoint.LINE) {
      //x=起始点+t*起始点和终点的距离
      x = startValue.mX + t * (endValue.mX - startValue.mX);
      y = startValue.mY + t * (endValue.mY - startValue.mY);
    } else {
      x = endValue.mX;
      y = endValue.mY;
 
    }
    return PathPoint.moveTo(x, y);
  }
}

注意:属性动画既可以改变属性,也可以改变一个变量或者方法

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/155603.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号