温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android实现炫酷播放效果的方法

发布时间:2021-04-17 09:36:59 来源:亿速云 阅读:217 作者:小新 栏目:移动开发

小编给大家分享一下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<PathPoint> 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<PathPoint> getPoints() {     return mPoints;   } }

3、实现页面布局

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:app="http://schemas.android.com/apk/res-auto"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:background="#ffe8e8e8">       <ImageView     android:id="@+id/album_cover"     android:layout_width="match_parent"     android:layout_height="250dp"     android:background="#22eeff" />     <android.support.v7.widget.Toolbar     android:id="@+id/toolbar"     android:layout_width="match_parent"     android:layout_height="120dp"     android:layout_below="@id/album_cover"     android:layout_marginTop="-15dp"     android:background="@color/colorPrimary"     android:elevation="4dp"     android:minHeight="?attr/actionBarSize"     android:paddingLeft="72dp">       <LinearLayout       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:gravity="center_vertical"       android:orientation="vertical">         <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:fontFamily="sans-serif"         android:text="大海大海"         android:textColor="#FFF"         android:textSize="30sp" />       <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center_vertical"         android:fontFamily="sans-serif-light"         android:text="王小二"         android:textColor="#9cffffff"         android:textSize="18sp" />     </LinearLayout>   </android.support.v7.widget.Toolbar>     <FrameLayout     android:id="@+id/fab_container"     android:layout_width="match_parent"     android:layout_height="128dp"     android:layout_below="@id/album_cover"     android:layout_marginTop="-30dp"     android:elevation="10dp">       <LinearLayout       android:id="@+id/media_controls_container"       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:layout_gravity="center"       android:orientation="horizontal">         <ImageView         android:layout_width="20dp"         android:layout_height="20dp"         android:scaleX="0"         android:scaleY="0"         android:src="@mipmap/play" />         <ImageView         android:id="@+id/iv_pause_play"         android:layout_width="20dp"         android:layout_height="20dp"         android:layout_marginLeft="50dp"         android:layout_marginRight="50dp"         android:scaleX="0"         android:scaleY="0"         android:src="@mipmap/play" />         <ImageView         android:layout_width="20dp"         android:layout_height="20dp"         android:layout_marginRight="50dp"         android:scaleX="0"         android:scaleY="0"         android:src="@mipmap/play" />       </LinearLayout>       <ImageButton       android:id="@+id/fab"       android:layout_width="56dp"       android:layout_height="56dp"       android:layout_gravity="top|right"       android:layout_marginRight="72dp"       android:background="@drawable/ripple"       android:elevation="5dp"       android:onClick="onPabPressed"       android:transitionName="button_fab" />   </FrameLayout>   </RelativeLayout>

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<PathPoint> {   @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);   } }

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

以上是“Android实现炫酷播放效果的方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI