2012-12-04 40 views
10

我想使用AccelerateDecelerateInterpolator和自定義它。 我可以看到像DecelerateInterpolator這樣的Interpolator有一個「factor」字段,所以你可以改變它的行爲。但AccelerateDecelerateInterpolator不具有。 當我使用AccelerateDecelerateInterpolator時,我幾乎無法注意到插補器在做任何事情。動畫看起來非常線性。那麼,有沒有什麼辦法來加速AccelerateDecelerateInterpolator或以任何方式改變它? 謝謝自定義android AccelerateDecelerateInterpolator

回答

9

你可以用自己的Interpolator執行標準寬鬆的功能。 例如,這將是對easeInOutQuint實施:

public class MVAccelerateDecelerateInterpolator implements Interpolator { 

    // easeInOutQuint 
    public float getInterpolation(float t) { 
     float x = t*2.0f; 
     if (t<0.5f) return 0.5f*x*x*x*x*x; 
     x = (t-0.5f)*2-1; 
     return 0.5f*x*x*x*x*x+1; 
    } 
} 

enter image description here

+0

僅供參考,功能easeInOutQuint可以在easings.net找到。 –

1

我試圖將自己的TimeInterpolator定義爲自定義AccelerateDecelerateInterpolator。我對結果並不滿意,但它可能會提供一些想法。代碼中還有一些因素:0.05f。檢查出來:

TimeInterpolator interpolator = new TimeInterpolator() { 
     @Override 
     public float getInterpolation(float input) { 
      return input + 0.05f * (float) Math.sin(2 * Math.PI * input); 
     } 
    }; 

這裏是更精緻的解決方案。切線對於工作來說可能是一個比正弦更好的功能。這個解決方案在開始和結束時逐漸加速。還有一個因素可以確定加速度。

TimeInterpolator interpolator = new TimeInterpolator() { 
     private final float mFactor = 1.1f; // less than pi/2 
     private float  oldRetVal; 
     private float  oldInputVal; 
     private double  initValue = Math.tan(-mFactor); 
     private double  endValue = 2 * Math.tan(mFactor); 

     @Override 
     public float getInterpolation(float input) { 
      if (oldInputVal != input) { 
       oldInputVal = input; 
       oldRetVal = (float) ((Math.tan(mFactor * (2 * input - 1)) - initValue)/endValue); 
      } 
      return oldRetVal; 
     } 
    }; 
1

Android已經加入PathInterpolatorCompat到V4支持庫。現在使用這個:https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce您可以輕鬆指定easeInOutQuint,easeInOutQuart或easeInOutExpo!

public static void expand(final View v) { 
     v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 
     final int targetHeight = v.getMeasuredHeight(); 

     if (v.getHeight() != targetHeight) { 
      // Older versions of android (pre API 21) cancel animations for views with a height of 0 so use 1 instead. 
      v.getLayoutParams().height = 1; 
      v.setVisibility(View.VISIBLE); 


      Animation a = new Animation() { 
       @Override 
       protected void applyTransformation(float interpolatedTime, Transformation t) { 
        v.getLayoutParams().height = interpolatedTime == 1 
          ? ViewGroup.LayoutParams.WRAP_CONTENT 
          : (int) (targetHeight * interpolatedTime); 
        v.requestLayout(); 
       } 

       @Override 
       public boolean willChangeBounds() { 
        return true; 
       } 
      }; 

      a.setInterpolator(EasingsConstants.easeInOutQuart); 
      a.setDuration(computeDurationFromHeight(v)); 
      v.startAnimation(a); 
     } else { 
      Log.d("AnimationUtil", "expand Already expanded "); 
     } 
    } 

/** 
* 1dp/ms * multiplier 
*/ 
private static int computeDurationFromHeight(View v) { 
    return (int) (v.getMeasuredHeight()/v.getContext().getResources().getDisplayMetrics().density) * DURATION_MULTIPLIER; 
} 

而且不要忘記你的build.gradle:

compile "com.android.support:support-v4:22.2.0" 
+0

從這個傢伙複製的擴展方法:http://stackoverflow.com/a/13381228/247325 –