I have an app using fragments, all of which are contained in a single activity. The activity starts with a fragment containing a menu of buttons, all of which cause various listfragments to replace the original button/menu fragment.
My problem is that upon an orientation change, if the activity is displaying one of the listviews, it goes away and the button menu returns. I understand why this is happening... the activity is destroyed and re-created, but not how to work around it and maintain the list view/current fragment through the orientation change.
I've found setRetainInstance
and the example of use here, but I can't figure out how to apply it to my situation with the button menu or the possibility that the fragment I want to retain could be one of several different ones.
Below is code simplified to show the main activity and one of the listfragments.
Any pointers in what to add where to make it so that the list fragment will be retained would be greatly appreciated.
Activity
public class Main extends FragmentActivity {
private MainMenuFragment menu;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
menu = new MainMenuFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.pane, menu).commit();
}
}
ListFragment
public class ItemListFragment extends ListFragment {
private TextView header;
private TextView empty;
private Button add;
public static Cursor itemCursor;
private GroceryDB mDbHelper;
public static long mRowId;
public static CheckCursorAdapter lists;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.common_list, container, false);
header = (TextView) v.findViewById(R.id.header);
empty = (TextView) v.findViewById(android.R.id.empty);
header.setText(R.string.header_item);
empty.setText(R.string.empty_items);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRowId=0;
mDbHelper = new GroceryDB(getActivity());
mDbHelper.open();
itemCursor = mDbHelper.fetchAllItems();
getActivity().startManagingCursor(itemCursor);
String[] from = new String[] { GroceryDB.ITEM_NAME };
int[] to = new int[] { R.id.ListItem };
lists = new CheckCursorAdapter(getActivity(),
R.layout.listlayout_itemlist, itemCursor, from, to);
setListAdapter(lists);
}
}
If you want to manually handle orientation changes in your app you must declare the "orientation" , "screenSize" , and "screenLayout" values in the android:configChanges attributes. You can declare multiple configuration values in the attribute by separating them with a pipe | character.
When you rotate your device and the screen changes orientation, Android usually destroys your application's existing Activities and Fragments and recreates them. Android does this so that your application can reload resources based on the new configuration.
A Fragment represents a reusable portion of your app's User Interface. Retained Fragment consists of the configuration change that causes the underlying Activity to be destroyed. The term "retained" refers to the fragment that will not be destroyed on configuration changes.
This article explains ListFragment in Android. A fragment that displays a list of items by binding to a data source such as an array or Cursor, and exposes event handlers when the user selects an item.
how to work around it and maintain the list view/current fragment through the orientation change
You are blindly replacing the fragment every time onCreate()
is called. Instead, only add/replace the fragment if savedInstanceState()
is null
. If it is not null
, you are coming back from a configuration change, and your existing fragments will be recreated (or, if they were retained, they are already there).
setRetainInstance(true)
means that the fragment itself will be retained across configuration changes, instead of being destroyed/recreated like the activity is. However, it will still be called with onCreateView()
. In your code, that means that your data members of ItemListFragment
would stick around, but you would still need to call setListAdapter()
even if you do not requery the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With