国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android實(shí)現(xiàn)炫酷播放效果

2019-10-21 21:41:17
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例為大家分享了Android實(shí)現(xiàn)播放效果的具體代碼,供大家參考,具體內(nèi)容如下

一、首先看效果

Android,炫酷播放

二、實(shí)現(xiàn)原理

使用貝塞爾曲線實(shí)現(xiàn)滑動(dòng)效果,在使用屬性動(dòng)畫(huà)實(shí)現(xiàn)水波紋效果,然后就能實(shí)現(xiàn)以上效果

三、實(shí)現(xiàn)

1、先封裝動(dòng)畫(huà)框架,創(chuàng)建動(dòng)畫(huà)基礎(chǔ)類

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、創(chuàng)建動(dòng)畫(huà)集合類,并且保存繪制軌跡

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、實(shí)現(xiàn)頁(yè)面布局

<?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、獲取控件,并且設(shè)置點(diǎn)擊事件,設(shè)置一些動(dòng)畫(huà)常量

private View mFab;  private FrameLayout mFabcontainer;  private LinearLayout mControlsContainer;   //從什么時(shí)候開(kāi)始執(zhí)行動(dòng)畫(huà)  private static final float SCALE_FACTOR = 13f;  //持續(xù)時(shí)間  private static final long ANIMATION_DURATION = 300;  //貝塞爾曲線滑動(dòng)到什么時(shí)候開(kāi)始執(zhí)行動(dòng)畫(huà)  private static final float MINIMUN_X_DISTANCE = 200;  private boolean mRevealFlag;  private float mFabSize;

5、給mFab設(shè)置點(diǎn)擊事件

private void onFabPressed(View view) {    final float startX = mFab.getX();    //開(kāi)始動(dòng)畫(huà)    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路徑中的某個(gè)位置就是開(kāi)始擴(kuò)散動(dòng)畫(huà)        if (Math.abs(startX - mFab.getX()) > MINIMUN_X_DISTANCE) {          if (!mRevealFlag) {            ImageButton fab = (ImageButton) mFab;            fab.setImageDrawable(new BitmapDrawable());            //看布局里邊的FabContainer要比toolbar背景高mFabSize/2(為了最初的半個(gè)fab效果)            mFabcontainer.setY(mFabcontainer.getY() + mFabSize / 2);            //fab放大動(dòng)畫(huà)            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) {      //因?yàn)椴季掷镞叺膍Fabcontainer要比toolbar背景高mFabSize/2,所以fab為了看起來(lái)平順,需要上移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動(dòng)畫(huà)完畢后,接著每一個(gè)子控件都有個(gè)縮放動(dòng)畫(huà)(依次順序出來(lái))      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執(zhí)行的百分比 (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=起始點(diǎn)+t*起始點(diǎn)和終點(diǎn)的距離      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);  }}

注意:屬性動(dòng)畫(huà)既可以改變屬性,也可以改變一個(gè)變量或者方法

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 壶关县| 洪湖市| 兴和县| 南汇区| 安阳县| 萝北县| 井陉县| 吉首市| 青冈县| 唐山市| 洞头县| 寻乌县| 武鸣县| 古浪县| 滦南县| 四子王旗| 南通市| 万源市| 深圳市| 晋江市| 嘉善县| 遵义县| 宣汉县| 香港| 泰和县| 吴桥县| 姜堰市| 秦安县| 山东| 泗阳县| 清徐县| 教育| 阿合奇县| 济阳县| 常熟市| 宁南县| 建昌县| 神农架林区| 大冶市| 青川县| 华宁县|