18

I am working with some fragments but the transition animations when switching from one to another is very laggy and sometimes it even skips the entire animation (which I've read that sometimes is an outcome of poor fragment performance).

The very intriguing thing is that all my data fetching and computation in that fragment is done completely async using coroutines set on computation threads. And the array lists containing the data are not even long or having many parameters. The only thing that I do on the UI thead is to set the final list on the RecyclerView Adapter and notifyDataSetChanged() -> that's all! So my conclusion is that the ViewHolder inflation itself is what causes the lag. The layout XMLs for the ViewHolders are as well very lite (a drawable res and three strings).

In terms of fragment transactions, I replace the current fragment with the new one in my FrameLayout and commit using a custom set of XML object animators.

I've seen some answers saying that I should delay setting the items on the Adapter for about 2 seconds, but hell, it would look really really bad for an end user to navigate in that fragment and wait 2 seconds on a white screen before the data suddenly shows up. I want a smooth 60fps transition to the new fragment, with the data already displayed.

Is this thing even possible on Android? I am not an apple fan, but as far as animations flow and smoothness, iOS devices wreck havoc on the mess that is Android at this subject.

I need any kinds of advices or even examples to show me how to fix this issue.

Thank you!

M'aiq the Coder
  • 762
  • 6
  • 18
  • Try using https://developer.android.com/studio/profile/cpu-profiler to measure what, exactly, is being slow. In general, what you describe is certainly possible. – Ben P. Feb 06 '20 at 18:23
  • have you fixed this issue finally? I have this problem too... – loalexzzzz Mar 25 '20 at 13:37
  • 4
    @loalexzzzz Sort of, it still micro-lags on bad phones and it always will so I'll just ignore it there. But on average-good phones released in the last 3 - 4 years, the problem was solved by creating the fragment instance when the activity starts. Instead of creating or replacing the fragment on button press and have the animation lag, I add the fragment on the creation of the activity and then hide it instantly. When navigating to the fragment, I just use show() instead of add()/replace() and it works smooth since the inflation was done before and doesn't interfere with animation on UI thread – M'aiq the Coder Mar 26 '20 at 08:59
  • thank you for your reply, I have finally found a solution, pls find below, hope this help you too. – loalexzzzz Mar 26 '20 at 13:06

1 Answers1

18

Try add a startOffset (like 300ms) when add/replace the fragment, fragment will pre-load from background, after 300ms, app will run the animation show your fragment smoothly.

300ms is just a random number, it's really depends on how heavy UI you need to init.

Hope this help.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="400"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        />
    <translate
        android:startOffset="300"
        android:fromYDelta="100%"
        android:toYDelta="0%"
        android:duration="400"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        />
</set>
loalexzzzz
  • 463
  • 1
  • 7
  • 16