Search code examples
androidandroid-listviewandroid-listfragmentfragmentpageradapter

FragmentPagerAdapter of ListFragments: how to load ListView selection?


I have a problem with a personal Android application that is driving me crazy.

I have an activity with a PagerSlidingTabStrip which is composed of a FragmentPagerAdapter with 4 fixed tabs, as on the picture below.

enter image description here

The first tab is a sort of summary, which reports the selections items done on the following tabs (2, 3 and 4 in the image). Each of the ListFragment is instantiated on the getItem method of the FragmentAdapter and I run this code when each ListFragment is loaded:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // Set adapter and options
    setListAdapter(mAdapter);
    getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

    // Code omitted
    // currentSelection is a field set by a method on the ListFragment

    // Load selection
    setSelectedItem(currentSelection);
}

public void setSelectedItem(int val) {  
    // Check if the ListView exists
    if (getActivity() != null) {
        // Set selection
        try {
            getListView().setItemChecked(val - 1, true);
        } catch (Exception e) {
            Log.e("myapp", "Exception while setting selection!");
        }
    }
}

So basically I'm calling a method on the ListFragment which sets the currentSelection integer variable to a number and when I swipe the tabs the ListFragments show the correct selected items. This works perfectly.

The problem raises when I try to update the lists on the code (i.e. updating the ListFragment adapters with new strings): I want to update the currentSelection too, based on values saved on my database.

This is what happens:

  1. I load a selection of "2-3-5" from the database and assign the field currentSelection of the three ListFragment tabs to those values.
  2. If I swipe to tab 2 and item number "2" is selected (see image, correct!)
  3. On tab 3, item number "3" is selected (correct!)
  4. On tab 4, item number "5" is selected (correct!)
  5. I load a new set of items and a selection of "1-2-3" from the database; then I assign the field currentSelection of the three ListFragment tabs again.
  6. On tab 4, the selection is refreshed and it's now "3" (correct!)
  7. I swipe to tab 3 and item number "2" is selected (correct!)
  8. I swipe to tab 2 and item number "2" is selected (WRONG as it's the old value!)

So on the tab number 2 (which is 2 tabs far from 4) the selection is not updated. Also, when I'm on tab 4 and update the data, the setSelectedItem method of tab 2 goes into the exception which is catched ("Content not yet created"). The activity exists, but the ListView seems unable to accept the selection with setItemChecked.

EDIT: When I move from tab 4 to 3 (step 7) onViewCreated of tab 2 is called and if there I call setSelectedItem it does NOT raise exceptions, but the selection is not set too.

How can I select the item I want on all the three tabs, if getListView() fails?


Solution

  • Also, when I'm on tab 4 and update the data, the setSelectedItem method of tab 2 goes into the exception which is catched ("Content not yet created").

    This is happening because you're too far away from the visible page which means that the view of the fragment get destroyed(for efficiency purposes).

    How can I select the item I want on all the three tabs, if getListView() fails?

    Move the setSelectedItem() method in the onResume() callback of the ListFragment. Right now, you do make the right setup to restore the selected item, but, as the fragment's view is destroyed and automatically restored(using the previous selection), you'll end up with the old value as the system restore happens after your call in onActivityCreated(). onResume() is the last callback to execute before the fragment is completely available so you'll be sure to have the last restore of currentSelection.