Я пытаюсь использовать AccelerateDecelerateInterpolator и настраиваю его. Я вижу, что у Interpolators, таких как DecelerateInterpolator, есть поле "factor", поэтому вы можете изменить его поведение. но AccelerateDecelerateInterpolator имеет нет. Когда я использую AccelerateDecelerateInterpolator, я почти не могу даже заметить, что интерполятор делает что-то. Анимация выглядит очень линейно. Итак, есть ли способ повлиять на AccelerateDecelerateInterpolator или каким-либо образом изменить его? Благодаря
Пользовательский андроид AccelerateDecelerateInterpolator
Ответ 1
Вы можете реализовать стандартную функцию ослабления со своим 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;
}
}
Ответ 2
Я попытался определить свой собственный 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;
}
};
Ответ 3
Android добавила PathInterpolatorCompat в библиотеку поддержки v4. Теперь, используя это: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce, вы легко можете указать легкостьInOutQuint, easeInOutQuart или easyInOutExpo!
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"