Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Child fragment not loading the second time inside FragmentStatePagerAdapter

I'm having an issue to display correctly fragments inside fragments with a FragmentStatePagerAdapter. The first time everything loads properly, but then the next time the view is blank. I tried this and this answers but it doesn't solve the issue.

So basically I have a FriendActivityFragment which is loaded inside MainActivity:

public class FriendActivityFragment extends Fragment {

private FriendsTabsPagerAdapter mAdapter;
private ViewPager mPager;
private SlidingTabLayout mTabs;

public FriendActivityFragment() {

}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (mAdapter == null) {
        //mAdapter = new FriendsTabsPagerAdapter(getActivity().getSupportFragmentManager());
        mAdapter = new FriendsTabsPagerAdapter(getChildFragmentManager());
    }

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_friend, container, false);
    super.onCreate(savedInstanceState);

    mPager = (ViewPager) view.findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);

    mTabs = (SlidingTabLayout) view.findViewById(R.id.tabs);
    mTabs.setDistributeEvenly(true);
    mTabs.setSelectedIndicatorColors(getResources().getColor(R.color.red));
    mTabs.setBackgroundColor(getResources().getColor(R.color.theme_color));
    mTabs.setViewPager(mPager);

    return view;

}

@Override
public void onResume() {
    super.onResume();
    mAdapter.notifyDataSetChanged();
}
}

Inside this fragment, I have set the FragmentStatePagerAdapter, which looks like this:

public class FriendsTabsPagerAdapter extends FragmentStatePagerAdapter {

    // Tab titles
    private String[] tabs = { "Friends", "Requests" };
    private FriendsListFragment[] mFragments;

    public FriendsTabsPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragments = new FriendsListFragment[tabs.length];
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabs[position];
    }

    @Override
    public Fragment getItem(int position) {
        if (mFragments[position] == null) {
            mFragments[position] = FriendsListFragment.getInstance(position);
        }

        return mFragments[position];
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 2;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }
}

And then I loads another fragment, FriendsListFragment, where my listView is:

public class FriendsListFragment extends Fragment {

    private View parentView;
    private ListView listView;
    private FriendListAdapter mAdapter;
    private TextView noFriends;


    public static FriendsListFragment getInstance(int position) {

        FriendsListFragment friendsListFragment = new FriendsListFragment();

        Bundle args = new Bundle();
        args.putInt("position", position);
        friendsListFragment.setArguments(args);

        return friendsListFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        parentView = inflater.inflate(R.layout.fragment_friend_list, container, false);
        listView   = (ListView) parentView.findViewById(R.id.listView);
        noFriends = (TextView) parentView.findViewById(R.id.noFriends);

        return parentView;
    }


    @Override
    public void onResume() {
        super.onResume();
        parentView.findViewById(R.id.avloadingIndicatorView).setVisibility(View.VISIBLE);
        initView();
    }

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public void initView() {

        QueryAPI query = new QueryAPI();

        Bundle bundle = getArguments();
        final int pos = bundle.getInt("position");

        if (bundle != null) {
            switch (pos) {
                case 0:
                    // Friend List
                    listView.setVisibility(View.VISIBLE);
                    parentView.findViewById(R.id.avloadingIndicatorView).setVisibility(View.VISIBLE);
                    query.friendList(new QueryAPI.ApiResponse<List<ModelFriend>>() {
                        @Override
                        public void onCompletion(List<ModelFriend> result) {
                            parentView.findViewById(R.id.avloadingIndicatorView).setVisibility(View.GONE);
                            if (result != null && !result.isEmpty()) {
                                if (mAdapter == null) {
                                    mAdapter = new FriendListAdapter(getActivity(), R.layout.fragment_friend_list_item, result);
                                }
                                listView.setAdapter(mAdapter);
                                mAdapter.notifyDataSetChanged();
                            } else {
                                noFriends.setVisibility(View.VISIBLE);
                            }
                        }
                    });
                    break;

                case 1:
                    // Friend Requests
                    parentView.findViewById(R.id.avloadingIndicatorView).setVisibility(View.VISIBLE);
                    query.friendRequestList(new QueryAPI.ApiResponse<List<ModelUser>>() {
                        @Override
                        public void onCompletion(List<ModelUser> result) {
                            parentView.findViewById(R.id.avloadingIndicatorView).setVisibility(View.GONE);
                            if (result != null && !result.isEmpty()) {
                                FriendRequestListAdapter adapter = new FriendRequestListAdapter(getActivity(), R.layout.fragment_friend_list_item, result);
                                listView.setAdapter(adapter);
                                adapter.notifyDataSetChanged();

                            } else {
                                noFriends.setText("No friend request.");
                                noFriends.setVisibility(View.VISIBLE);
                            }
                        }
                    });
                    break;
            }
        }

    }

}

Any idea what the problem might be?

EDIT: the crash log if I return super.saveState();

03-14 13:50:29.965 12418-12418/com.kalianey.oxapp E/FragmentManager: Fragment no longer exists for key f0: index 0
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp E/FragmentManager: Activity state:
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:   Active Fragments in 53f7ca48:
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     #0: null
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     #1: null
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:   Added Fragments:
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     #0: FriendsListFragment{53dde390}
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     #1: FriendsListFragment{53dde4dc}
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:   FragmentManager misc state:
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     mHost=null
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     mContainer=null
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     mCurState=0 mStateSaved=true mDestroyed=true
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/FragmentManager:     mAvailIndices: [0, 1]
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp D/AndroidRuntime: Shutting down VM
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa4ce9b20)
03-14 13:50:29.965 12418-12418/com.kalianey.oxapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                    Process: com.kalianey.oxapp, PID: 12418
                                                                    java.lang.IllegalStateException: Fragment no longer exists for key f0: index 0
                                                                        at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:673)
                                                                        at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
                                                                        at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1319)
                                                                        at android.view.View.dispatchRestoreInstanceState(View.java:12799)
                                                                        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2637)
                                                                        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2643)
                                                                        at android.view.View.restoreHierarchyState(View.java:12777)
                                                                        at android.support.v4.app.Fragment.restoreViewState(Fragment.java:471)
                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1105)
                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
                                                                        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
                                                                        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                                                                        at android.os.Handler.handleCallback(Handler.java:733)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                        at android.os.Looper.loop(Looper.java:136)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5001)
                                                                        at java.lang.reflect.Method.invokeNative(Native Method)
                                                                        at java.lang.reflect.Method.invoke(Method.java:515)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                        at dalvik.system.NativeStart.main(Native Method)
03-14 13:55:30.165 12418-12418/? I/Process: Sending signal. PID: 12418 SIG: 9
like image 846
Kali Aney Avatar asked Mar 10 '16 13:03

Kali Aney


2 Answers

I have encountered this problem a few weeks ago,and always has some wrong with saveState() or restoreState() in FragmentStatePagerAdapter, so I understand why you try to return null in saveState().

First I advised you use FragmentPagerAdapter instead of FragmentStatePagerAdapter, and add this in your Adapter:

@Override
public int getItemPosition(Object object) {
    return PagerAdapter.POSITION_NONE;
}

If it doesn't work for you, maybe you'd like to create you own PageAdapter directly inherit from PageAdapter, and copy the FragmentPagerAdapter's code into your PageAdapter. If you insist to use restoreState() and saveState(), just follow FragmentStatePagerAdapter and debug it.

This may seems trouble, but after I implemented my PageAdapter, I would never afraid of any qestions about viewpage + fragment.

like image 64
Davis Avatar answered Nov 19 '22 02:11

Davis


I have also face same issue and i fixed by changing some point in fragmentAdapter and in Parent fragment.

  1. First check you extend FragmentPagerAdapter in FriendsTabsPagerAdapter.
  2. When you create an object of FriendsTabsPagerAdapter you must be pass getChildFragmentManager() method instead of getActivity().getSupportFragmentManager().

I changed only these two point any my fragment work properly.

like image 27
Ashik Abbas Avatar answered Nov 19 '22 02:11

Ashik Abbas