I am using one activity all fragment approach. Now I have a fragment A and when I go to fragment B I replace A in container with B with
.replace(R.id.master_fragment_container_above_toolbar, fragment)
.addToBackStack("")
.commit();
As you can see, I have added fragment to backStack. But now when I press back on device, it re-instantiates the fragment A and thus takes time to go back.
Is there another way to do it? I don't want to use add()
, if I add multiple fragments to container, it will take up a lot of memory.
The short answer - there's no silver bullet in your case. You'll have to use replace()
and it will re-create fragment's View
on going back. That's "by design".
The good news is that there're a few tricks you can do to make it less dramatic for UX.
Cache whatever you can. If you load content from web - write it into the local SQLite db. And fill the screen from Local Storage while refreshing the data from the server.
In onCreateView()
avoid re-creating Adapters once they are already exist. If user is getting back to FragmentA from the FragmentB, FragmentA will recreate its View
. But it doesn't mean, that local variables are null at this point. So I do it like this:
public class FeedFragment extends Fragment {
private FeedAdapter adapter;
......
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = initialize(inflater, container, R.layout.fragment_with_recyclerview);
....
if (adapter == null) {
adapter = new FeedAdapter();
}
RecyclerView recyclerView = (RecyclerView)rootView.findViewById(R.id.recyclerView)
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
return rootView;
}
}
It matters, because filling TextView
s, etc. are so fast operations, that you don't really care about it, while huge ListView
or RecyclerView
can be much more expensive;
Use image-caching and good image-loading tool. I'd recommend Picasso from Square. It has automatic memory and disk caching;
Try to logically decouple your app. Let's take a Gmail-style application, as an example:
It has NavigationDrawer
, which is switching user through the root fragments (i.e. no need to keep navigation stack). Once you open mail-thread - it replaces the root fragment with MailThread fragment. There you can consume the content.
But once you click on "Compose email" - you are redirecting to a separate Activity
- as you move from consuming content to composing content state (I.e. significant change in user's behaviour: new user scenario == new activity).
Many top developers go even further and having Activities for pretty much everything. Twitter (and it's satellite products) as an example. But personally, I prefer to keep it in balance (as opening new activity is an expensive operation from perf. point of view).