Since I wasn't able to eliminate the animation freeze entirely, I ended up going a slightly different route. Instead of stopping the animation and toggling the layouts after I finish created all the modules' Views
, I stop the animation and toggle the layouts after the first module is loaded, then load each subsequent module incrementally. I used a separate HandlerThread
so I wasn't triggered the modules all on the main UI thread.
private ArrayList<Modules> modules;
private HandlerThread mThread;
private ModuleThreadHandler mThreadHandler;
@Override
public void onStart(){
super.onStart();
LoaderManager lm = getLoaderManager();
lm.initLoader(LOADER_PROFILE, getArguments(), this);
loadingAnimation.start();
animationLayout.setVisibility(LinearLayout.VISIBLE);
mainLayout.setVisibility(ViewGroup.GONE);
}
@Override
public void onLoadFinished(Loader<Response> responseLoader, Response response) {
modules = response.modules;
mThread = new HandlerThread("mThread");
mThread.start();
Looper mThreadLooper = mThread.getLooper();
mThreadHandler = new ModuleThreadHandler(mThreadLooper);
mThreadHandler.obtainMessage(0).sendToTarget();
}
private class ModuleThreadHandler extends Handler {
public ModuleThreadHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
fragmentHandler.obtainMessage(msg.what + 1).sendToTarget();
}
}
private Handler fragmentHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what < modules.size()) {
Module m = modules.get(msg.what);
switch (m.Type) {
case Type1:
mainLayout.addView(Type1Module.getView(inflater, m));
break;
case Type2:
mainLayout.addView(Type2Module.getView(inflater, m));
break;
case Type3:
mainLayout.addView(Type3Module.getView(inflater, m));
break;
case Type4:
mainLayout.addView(Type4Module.getView(inflater, m));
break;
case Type5:
mainLayout.addView(Type5Module.getView(inflater, m));
break;
}
}
if (msg.what == 0) {
loadingAnimation.stop();
animationLayout.setVisibility(LinearLayout.GONE);
mainLayout.setVisibility(ViewGroup.VISIBLE);
}
if ((msg.what + 1) < modules.size()) {
pThreadHandler.obtainMessage(msg.what).sendToTarget();
} else {
pThread.quit();
}
}
};
This has the nice (IMO) side-effect of a "loading" effect as the modules load rapidly in succession. I found this to load just as fast as using a ListView
. The only downside of this approach is that, while the modules are loading, scrolling is choppy (as there is work being done on the UI thread). However, once all modules are loaded, scrolling is very smooth (which was the main goal in the first place).