ProgressBar not animating while inflating viewstub
Asked Answered
F

2

7

I have an Activity with this structure:

FrameLayout
   ProgressBar
   ViewStub

The ViewStub inflates a Fragment in a separate thread. What I need is to display the progress while the fragment loads. The problem is the ProgressBar is not spinning while the stub inflates (in my case about half a second: it's a heavy fragment) I've tried everything: showing/hiding the view, invalidate, show them in ViewSwitchers...etc, nothing works, as soon as the ViewStub inflates, it starts spinning, it's like the ui is frozen while it inflates but doing it in another thread doesn't seem to improve. What should I do?

Frier answered 23/7, 2014 at 12:1 Comment(6)
call the progress from the UI thread of your main activity and then all the heavy stuff should be moved to a separate thread or asyncTaskWhitneywhitson
What should I do? - you improve the view hierarchy so it's shallower and smaller in size. Of course any data except basic lists should be loaded on a background thread.Vive
It's already loading in a separate thread and the view hierarchy is as optimized as possible. The question is, is inflating a ViewStub always loading on UI thread, even if I put it in a separate thread? because it seems like it freezes the UIFrier
How exactly do you inflate the ViewStub on a background thread?Vive
viewStub.post(new Runnable() { @Override public void run() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST); viewStub.inflate(); initFragment(); } });Frier
Well that method(post()) clearly says The runnable will be run on the user interface thread so you aren't doing anything on another background thread. Second of all you shouldn't instantiate views on a background thread because they create stuff like handlers which may be tied to the wrong thread(instead of the UI thread). Keep in mind that all of the fragment's callbacks will be run when you inflate the ViewStub containing the embedded fragment, also make sure that if you load heavy data in the initFragment() method you actually use a background thread.Vive
P
4

The fragment must be loaded on the UI thread, and because the UI is busy with the fragment the ProgressBar doesnt spin. You need to seperate the data loading in the fragment to the UI stuff. I would test and check what exactly is running and keeping the fragment from starting up fast , i would use a loader in order to load the data while presenting a progressbar to the user (inside the fragment) . Yes, move the progress to the layout of the fragment and control everything from there because i dont the activity to know when the fragment is done loading, the activity doesnt suppose to care about that.

Pachston answered 10/6, 2015 at 16:38 Comment(0)
F
2

Basically what @Luksprog said in his comment is correct if you call viewStub.post() this does NOT run the code inside the post on a background thread. All it does is post the runnable to the UI thread. It may work if you do

new Thread(new Runnable() {
    @Override
    public void run() {
        viewStub.inflate();
        initFragment();
    }
}).start()

Although as @Luksprog also stated - it's bad practice to instantiate views on a background thread. So perhaps the best solution is to move the .inflate() call outside (onto the main thread), and then call initFragment() from the background thread and put all the heavy lifting in there.

Federalese answered 16/6, 2015 at 23:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.