Этот вопрос все еще действует почти в середине 2017 года. Я хотел создать плавный переход для изменения цвета для своего пользовательского вида.Я использовал шейдеры с LinearGradients.
Мое намерение состояло в том, чтобы сделать плавный переход между включенным и отключенным состоянием моего обзора.
Мой случай еще сложнее из-за конструкции и цели обзора.Это слайдер.Таким образом, мой взгляд состоит из почти 2 одинаковых слоев, нарисованных один поверх второго с помощью холста.Третий элемент - это указатель.
В обоих слоях используется LinearGradients, в указателе используется один цвет.
Суммируя все, что мне нужно для перехода между 5 цветами одновременно:
- начальный и конечный цвет для нижнего слоя - один LinearGradient,
- начальный и конечный цвет для верхнего слоя - второй LinearGradient,
- цвет указателя - обычный цвет;
Решением этой проблемы является наличие 5 отдельных ValueAnimators.Наиболее важным является использование ValueAnimator.ofArgb ():
private ValueAnimator frontStartColorAnimator;
private ValueAnimator frontEndColorAnimator;
private ValueAnimator bottomStartColorAnimator;
private ValueAnimator bottomEndColorAnimator;
private ValueAnimator pointerColorAnimator;
private AnimatorSet colorsAnimatorSet;
...
frontStartColorAnimator = ValueAnimator.ofArgb(frontLayerStartColor, frontLayerDisabledStartColor);
frontStartColorAnimator.setDuration(animationDuration);
frontStartColorAnimator.setInterpolator(new LinearInterpolator());
frontStartColorAnimator.addUpdateListener(animation
-> shaderFrontLayerStartColor = (int) animation.getAnimatedValue());
frontEndColorAnimator = ValueAnimator.ofArgb(frontLayerEndColor, frontLayerDisabledEndColor);
frontEndColorAnimator.setDuration(animationDuration);
frontEndColorAnimator.setInterpolator(new LinearInterpolator());
frontEndColorAnimator.addUpdateListener(animation -> {
shaderFrontLayerEndColor = (int) animation.getAnimatedValue();
frontLayerPaint.setShader(new LinearGradient(0, 0, getWidth(), 0, shaderFrontLayerStartColor,
shaderFrontLayerEndColor, Shader.TileMode.CLAMP));
});
bottomStartColorAnimator = ValueAnimator.ofArgb(bottomLayerStartColor, bottomLayerDisabledStartColor);
bottomStartColorAnimator.setDuration(animationDuration);
bottomStartColorAnimator.setInterpolator(new LinearInterpolator());
bottomStartColorAnimator.addUpdateListener(animation ->
shaderBottomLayerStartColor = (int) animation.getAnimatedValue());
bottomEndColorAnimator = ValueAnimator.ofArgb(bottomLayerEndColor, bottomLayerDisabledEndColor);
bottomEndColorAnimator.setDuration(animationDuration);
bottomEndColorAnimator.setInterpolator(new LinearInterpolator());
bottomEndColorAnimator.addUpdateListener(animation -> {
shaderBottomLayerEndColor = (int) animation.getAnimatedValue();
backLayerPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), shaderBottomLayerStartColor,
shaderBottomLayerEndColor, Shader.TileMode.CLAMP));
});
pointerColorAnimator = ValueAnimator.ofArgb(pointerEnabledColor, pointerDisabledColor);
pointerColorAnimator.setDuration(animationDuration);
pointerColorAnimator.setInterpolator(new LinearInterpolator());
pointerColorAnimator.addUpdateListener(animation -> {
pointerColor = (int) animation.getAnimatedValue();
pointerPaint.setColor(pointerColor);
});
colorsAnimatorSet = new AnimatorSet();
colorsAnimatorSet.playTogether(frontStartColorAnimator, frontEndColorAnimator,
bottomStartColorAnimator, bottomEndColorAnimator, pointerColorAnimator);
...
colorsAnimatorSet.start();
При запуске я также беспокоился о создании нового LinearGradient при каждом обновлении анимации, но затем я запустил профилирование GPU на устройстве с надписью «На экране какбары».Все хорошо и работает в пределах допустимого.