#android #android-animation
Вопрос:
Я пытаюсь создать очень «простую» анимацию, основанную на анимации цен на фондовом рынке, для моего приложения для Android.
идея очень проста, получить фон textview -> перейти на зеленый ->> вернуться к оригиналу.
Единственный способ, который я могу придумать для этого, — это создать зеленое представление с точно таким же размером и положением текстового представления, использовать анимацию, чтобы она исчезла, а затем установить видимость невидимой… но мне это кажется неправильным, есть ли лучший подход к этому?
Ответ №1:
Эта анимация может быть достигнута с помощью двух ViewPropertyAnimators
из TextView
них: из начального состояния (Прозрачное фоновое состояние) в Выделенное (Зеленое фоновое состояние) и наоборот. У каждого ViewPropertyAnimator
есть Runnable
EndAction
функция, которая вызывается по завершении анимации, где цвет фона TextView может быть изменен соответствующим образом.
Пример показан ниже:
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
tv = findViewById(R.id.tv);
getHighlightedViewPropertyAnimator().start();
}
private ViewPropertyAnimator getInitialViewPropertyAnimator(){
return tv.animate().alpha(1).setDuration(1000).withEndAction(initialEndAction);
}
private ViewPropertyAnimator getHighlightedViewPropertyAnimator(){
return tv.animate().alpha(1).setDuration(1000).withEndAction(highlightedEndAction);
}
private final Runnable initialEndAction = new Runnable() {
@Override
public void run() {
tv.setBackgroundColor(Color.TRANSPARENT);
tv.setTextColor(Color.GREEN);
getHighlightedViewPropertyAnimator().start();
}
};
private final Runnable highlightedEndAction = new Runnable() {
@Override
public void run() {
tv.setBackgroundColor(Color.GREEN);
tv.setTextColor(Color.WHITE);
getInitialViewPropertyAnimator().start();
}
};
И когда вы захотите отменить анимацию, вы можете это сделать:
tv.animate().cancel();
Результат:
Комментарии:
1. хороший подход, но я нашел более прямой путь
Ответ №2:
Мне потребовалось некоторое время, чтобы подумать, но решение может быть сделано очень легко
public class TextViewHighlighter {
private static final Handler main = new Handler(Looper.getMainLooper());
private static int originalColor = -1;
private TextViewHighlighter(){
}
@MainThread
public static void highlightTextChange(@Nullable final String newText, @ColorInt final int hightlightColor, @NonNull final TextView txtView) {
txtView.setText(newText);
txtView.setBackgroundColor(hightlightColor);
//only main thread, dont need to synchronize
if (originalColor == -1)
originalColor = txtView.getCurrentTextColor();
txtView.setTextColor(Color.WHITE);
main.postDelayed((Runnable) () -> {
if (txtView.getText().equals(newText)) {
txtView.setBackground(null);
txtView.setTextColor(originalColor);
}
}, 350);
}
}
Это очень похоже на идею @MariosP, но все инкапсулировано в одном статическом методе и без всей animate()
этой композиции, которая на самом деле не нужна
единственный недостаток, учитывая мою первоначальную мысль, заключается в том, что при использовании этого нет интерполяции… вид текста меняется с ОБЫЧНОГО на ВЫДЕЛЕННЫЙ в одном кадре… никакого постепенного процесса затухания.
но в конце концов визуальный результат — это именно то, что я хочу