Анимируйте только фон текстового представления Android

#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() этой композиции, которая на самом деле не нужна

единственный недостаток, учитывая мою первоначальную мысль, заключается в том, что при использовании этого нет интерполяции… вид текста меняется с ОБЫЧНОГО на ВЫДЕЛЕННЫЙ в одном кадре… никакого постепенного процесса затухания.

но в конце концов визуальный результат — это именно то, что я хочу