Animate only the background of android textview

Viewed 151

I'm trying to create a very "simple" animation based on the stock market price animation for my android app.

enter image description here

the idea is very simple, get textview background -> fade to green -> return to original.

The only way i can think of doing this is have a green view, with the exact same size and position of the textview, use animation fade it then set visibility to invisible... but it looks not right to me, is there a better approach to this?

2 Answers

This animation can be achieved using two ViewPropertyAnimators of TextView one from Initial State (Transparent Background State) to Highlighted (Green Background State) and one vice versa. Each ViewPropertyAnimator has a Runnable EndAction which is called when the animation has finished where the TextView background colour can be changed accordingly.

Example is shown below:

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();
    }
};

And when you want to cancel the animation you can do:

tv.animate().cancel();

Result:

animation_sample

I took some time to think but the solution can be done very easily

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);

    }
}

This is very similar @MariosP idea but all is encapsulated in one single static method and without that whole animate() composition that isn't really necessary

the only con considering my original thought, is that by using this there is no interpolation... the textview goes from NORMAL, to HIGHLIGHT in one frame... no gradual fade process.

but at the end the visual result is exact what i want

Related