Search code examples
androidandroid-fragmentsandroid-listfragmentback-stackandroid-nested-fragment

ListFragment loads empty list after coming back from BackStack


this is my 2nd post on same matter, I am still waiting for someone to guide me. The issue I am facing may be very simple, in short I have this ListFragment which populates the list calling a webservice, this works fine. When user selects any item I replace another fragment and add this one to BackStack

the issue starts here, it pops the ListFragment but it's always empty or blank. But I've checked logs in every possible way and found the data is there, for some reason the list stays blank. Please help me someone...

In MainActivity I use DrawerItemCustomAdapter and this is how I replace fragments

private void selectItem(int position) {

    android.support.v4.app.Fragment fragment = null;

    switch (position) {
    case 0:
    {
        fragment = new EventFragment();
    }
        break;
    case 1:
        fragment = new ScheduleFragment();
        break;
    case 2:
        fragment = new NewsFragment();
        break;
    case 3:
        fragment = new TeamFragment();
        break;
    case 4:
        fragment = new VenueFragment();
        break;
    case 5:
        fragment = new NewsFragment();
        break;

    default:
        break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();  

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);

    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }

}

in EventFragment I use FragmentStatePagerAdapter to create ViewPager

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.event_fragment, container, false);

    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();

    viewpager = (ViewPager)rootView.findViewById(R.id.pager);

    viewpager.setAdapter(new MyAdapter(fragmentManager));

    return rootView;
}

and In the MyAdapter class

    class MyAdapter extends FragmentStatePagerAdapter {

        FragmentManager fragmentManager;
    public MyAdapter(FragmentManager fm) {
            super(fm);
            // TODO Auto-generated constructor stub
            fragmentManager = fm;
        }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = null;

        if(i == 0)
        {
            fragment = new LiveFragment();
        }
        if(i == 1)
        {
            fragment = new UpcomingFragment();
        }
        if(i == 2)
        {
            fragment = new CompletedFragment();
        }

        return fragment;
    }
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return 3;
}

@Override
    public CharSequence getPageTitle(int position) {
        if(position == 0)
        {
            return "Live";
        }
        if(position == 1)
        {
            return "Up-Coming";
        }
        if(position == 2)
        {
            return "Completed";
        }

        return null;
    }
    }

All three tabs are ListFragment let's pick the first one

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {

                LiveMatchList = new ArrayList<HashMap<String, Object>>();
                adapter = null;
                Log.d("LiveMatchList setUserVisibleHint","setUserVisibleHint");
                new LoadUpcomingMatchList().execute();          
        }
    }

my LoadUpcomingMatchList class extends AsyncTask, and after onPreExecute and doInBackground I set the adapter like this

protected void onPostExecute(String file_url) {
            try
            {
                if (pDialog != null) { 
                    pDialog.dismiss();
               }
                //pDialog.dismiss();
                /**
                 * Updating parsed JSON data into ListView
                 * */
                adapter = new SimpleAdapter(
                        getActivity(),LiveMatchList,
                        R.layout.live_list_row, new String[] { TAG_DateTimeLabel, "eventName", TAG_roundName, TAG_Venue, "team1Flag", "team2Flag" },
                        new int[] { R.id.livematchDate, R.id.livematchName, R.id.liveround, R.id.livevenue, R.id.liveteam1flag, R.id.liveteam2flag });
                // updating listview
                setListAdapter(adapter);
                Log.d("LiveMatchList onPostExecute",String.valueOf(LiveMatchList));
            }
            catch(Exception ex)
            {
                Log.d("onPostExecute", ex.toString());
            }

        }

I've implemented onListItemClick to goto details page from MainActivity, like you suggested.

@Override
    public void onListItemClick(ListView l, View v, int position, long id) { 

        @SuppressWarnings("unchecked")
        HashMap<String,String> selectedItem = (HashMap<String, String>) getListView().getItemAtPosition(position);
        Bundle dataBundle = new Bundle();
        dataBundle.putString("team1Id", selectedItem.get(TAG_homeTeamId));
        dataBundle.putString("team2Id", selectedItem.get(TAG_awayTeamId));


        ((MainActivity)getActivity()).doTransaction("LiveFragment", dataBundle);

        Fragment fragment = new LiveMatchDetailMainFragment();
        fragment.setArguments(dataBundle);
        android.support.v4.app.FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.content_frame, fragment);
        fragmentTransaction.addToBackStack("LiveFragment");
        fragmentTransaction.commit();
    }

the detail page is again a fragment with viewPager implemented. Now when I press back button from detail page it loads the previous fragment as expected and I've checked the log where I can see setUserVisibleHint is called and the tab is loaded as expected but there is nothing in the tab, there should be a list. please refer to the diagram, if that helps, thank you so much for your help. I've wasted 3/4 days on this issue already.

   [MainActivity]
         |
         V
   [EventFragment]
   |     |      | 
   V     V      V
[Tab1] [Tab2] [Tab3]

[Tab1] is a ListFragment implements onListItemClick -> Detail Fragment.


Solution

  • Are you doing your fragment transactions within your ListFragment? Do that in the FragmentActivity and use your onListItemClick() callback method to call a FragmentActivity method, which should run the transaction.

    In EventFragment replace:

    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    viewpager.setAdapter(new MyAdapter(fragmentManager));
    

    with:

    viewpager.setAdapter(new MyAdapter(getChildFragmentManager()));