Sto cercando di utilizzare AccelerateDecelerateInterpolator e personalizzato. Posso vedere che gli Interpolator come DecelerateInterpolator hanno un campo "fattore" in modo da poter cambiare i suoi comportamenti. ma AccelerateDecelerateInterpolator ha non. Quando utilizzo AccelerateDecelerateInterpolator quasi non riesco nemmeno a notare che l'interpolatore sta facendo qualsiasi cosa. L'animazione sembra molto lineare. Quindi, c'è un modo per considerare AccelerateDecelerateInterpolator o modificarlo in qualche modo? GrazieAndroid personalizzato AccelerateDecelerateInterpolator
risposta
È possibile implementare funzione di andamento di serie con il proprio Interpolator
. Per esempio, questo sarebbe l'implementazione per il 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;
}
}
Ho provato a definire il mio TimeInterpolator come un AccelerateDecelerateInterpolator personalizzato. Non sono molto contento del risultato, ma potrebbe dare qualche idea. C'è anche una sorta di fattore nel codice: 0.05f. Check it out:
TimeInterpolator interpolator = new TimeInterpolator() {
@Override
public float getInterpolation(float input) {
return input + 0.05f * (float) Math.sin(2 * Math.PI * input);
}
};
Qui è la soluzione più raffinata. Tangente è probabilmente una funzione migliore per il lavoro, rispetto a seno. Questa soluzione accelera all'inizio e alla fine. C'è anche un fattore per determinare l'accelerazione.
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;
}
};
Android ha aggiunto PathInterpolatorCompat per la libreria di supporto v4. Ora usando questo: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce puoi specificare facilitàInOutQuint, facilitàInOutQuart o facilitàInOutExpo con facilità!
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;
}
E non dimenticate il vostro build.gradle:
compile "com.android.support:support-v4:22.2.0"
espandi il metodo copiato da questo ragazzo: http://stackoverflow.com/a/13381228/247325 –
Cordiali saluti, la funzione easeInOutQuint può essere trovato alla easings.net. –