欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2018年08月17日 09:57:29   作者:wanxiaofan  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)炫酷播放效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

一、首先看效果

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

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

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

1、先封裝動畫框架,創(chuàng)建動畫基礎(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)建動畫集合類,并且保存繪制軌跡

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)頁面布局

<?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è)置一些動畫常量

private View mFab;
  private FrameLayout mFabcontainer;
  private LinearLayout mControlsContainer;
 
  //從什么時候開始執(zhí)行動畫
  private static final float SCALE_FACTOR = 13f;
  //持續(xù)時間
  private static final long ANIMATION_DURATION = 300;
  //貝塞爾曲線滑動到什么時候開始執(zhí)行動畫
  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();
    //開始動畫
    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路徑中的某個位置就是開始擴(kuò)散動畫
        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) {
      //因?yàn)椴季掷镞叺膍Fabcontainer要比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執(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);
  }
}

注意:屬性動畫既可以改變屬性,也可以改變一個變量或者方法

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android使用屬性動畫如何自定義倒計時控件詳解

    Android使用屬性動畫如何自定義倒計時控件詳解

    自Android 3.0版本開始,系統(tǒng)給我們提供了一種全新的動畫模式,屬性動畫(property animation),它的功能非常強(qiáng)大,下面這篇文章主要給大家介紹了關(guān)于Android使用屬性動畫如何自定義倒計時控件的相關(guān)資料,需要的朋友可以參考下
    2018-05-05
  • Crashlytics Android 異常報告統(tǒng)計管理(詳解)

    Crashlytics Android 異常報告統(tǒng)計管理(詳解)

    下面小編就為大家?guī)硪黄狢rashlytics Android 異常報告統(tǒng)計管理(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Android中Serializable和Parcelable序列化對象詳解

    Android中Serializable和Parcelable序列化對象詳解

    這篇文章主要介紹了Android中Serializable和Parcelable序列化對象的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android仿知乎懸浮功能按鈕FloatingActionButton效果

    Android仿知乎懸浮功能按鈕FloatingActionButton效果

    前段時間在看屬性動畫,恰巧這個按鈕的效果可以用屬性動畫實(shí)現(xiàn),下面通過本文給大家分享adroid仿知乎懸浮功能按鈕FloatingActionButton效果,需要的朋友參考下吧
    2017-04-04
  • Android仿微信照片選擇器實(shí)現(xiàn)預(yù)覽查看圖片

    Android仿微信照片選擇器實(shí)現(xiàn)預(yù)覽查看圖片

    這篇文章主要介紹了Android仿微信照片選擇器實(shí)現(xiàn)預(yù)覽查看圖片的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Flutter如何保證數(shù)據(jù)操作原子性詳解

    Flutter如何保證數(shù)據(jù)操作原子性詳解

    這篇文章主要給大家介紹了關(guān)于Flutter如何保證數(shù)據(jù)操作原子性的相關(guān)資料,文章通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-03-03
  • Android?Spinner和GridView組件的使用示例

    Android?Spinner和GridView組件的使用示例

    Spinner其實(shí)是一個列表選擇框,不過Android的列表選擇框并不需要顯示下拉列表,而是相當(dāng)于彈出一個菜單供用戶選擇,GridView是一個在二維可滾動的網(wǎng)格中展示內(nèi)容的控件。網(wǎng)格中的內(nèi)容通過使用adapter自動插入到布局中
    2022-03-03
  • Android多進(jìn)程間采用AIDL方式進(jìn)行通信

    Android多進(jìn)程間采用AIDL方式進(jìn)行通信

    這篇文章主要為大家詳細(xì)介紹了Android多進(jìn)程間采用AIDL方式進(jìn)行通信,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android AndroidX的遷移

    Android AndroidX的遷移

    這篇文章主要介紹了Android AndroidX的遷移,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Android中SharedPreferences簡單使用實(shí)例

    Android中SharedPreferences簡單使用實(shí)例

    這篇文章主要介紹了Android中SharedPreferences簡單使用案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評論