Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android animation reduce stutter/choppy/lag

So I've been having animation issues especially when two animations happen at once or right when an activity loads. I understand it's probably a resource problem and a lot of things are going on in the main thread causing the animations to stutter.

I've found a couple interesting suggestions:
1. Threads (ThreadPoolExecutor)
Here: How do I make my animation smoother Android
2. setDrawingCacheEnabled(true)
Here: How does Android's setDrawingCacheEnabled() work?
3. ViewGroup: animationCache = true
Here: http://www.curious-creature.org/2010/12/02/android-graphics-animations-and-tips-tricks/

However I haven't been able to find any sort of examples to implement these things. Any ideas?

like image 520
Rawr Avatar asked Sep 09 '25 22:09

Rawr


2 Answers

I've reduced the amount of stutter on my animations by following these rules listed in order of importance when reducing stutter:

  1. Don't initiate animations in onCreate, onStart or onResume.
  2. Initiate animations on user events such as onClick and disable touch events until animation is complete.
  3. Don't initiate more than 2 animations simultaneously.
like image 121
Rawr Avatar answered Sep 12 '25 14:09

Rawr


If you are using animation you should follow the android docs; in fact in some cases, you might need to postpone your fragment transition for a short period of time. For example in my case I need to postpone my animation until my viewmodel return some data:

Use postponeEnterTransition() in the entering fragment onViewCreated() method:

public class A extends Fragment {

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        ...
        postponeEnterTransition();
    }
}

Once the data are ready to start the transition, call startPostponedEnterTransition()

public class A extends Fragment {

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        postponeEnterTransition();

        final ViewGroup parentView = (ViewGroup) view.getParent();
        // Wait for the data to load
        viewModel.getData()
            .observe(getViewLifecycleOwner(), new Observer<List<String>>() {
                @Override
                public void onChanged(List<String> list) {
                    // Set the data on the RecyclerView adapter
                    adapter.setData(list);
                    // Start the transition once all views have been
                    // measured and laid out
                    parentView.getViewTreeObserver()
                        .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                            parentView.getViewTreeObserver()
                                .removeOnPreDrawListener(this);
                            startPostponedEnterTransition();
                            return true;
                        });
                }
        });
    }
}
like image 41
G. Ciardini Avatar answered Sep 12 '25 12:09

G. Ciardini