【问题标题】:Android - Child fragment not loading the second time inside FragmentStatePagerAdapterAndroid - 子片段没有在 FragmentStatePagerAdapter 中第二次加载
【发布时间】:2016-03-10 13:27:31
【问题描述】:

我在使用 FragmentStatePagerAdapter 正确显示片段内的片段时遇到问题。第一次一切都正确加载,但下一次视图是空白的。我尝试了thisthis 的答案,但并没有解决问题。

所以基本上我有一个加载在 MainActivity 中的 FriendActivityFragment:

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();
}
}

在这个片段中,我设置了 FragmentStatePagerAdapter,如下所示:

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;
    }
}

然后我加载另一个片段 FriendsListFragment,我的 listView 是:

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;
            }
        }

    }

}

知道可能是什么问题吗?

编辑:如果我返回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

【问题讨论】:

  • 我认为你应该在 onCreateView 而不是 onCreate 中实例化你的 madapter
  • 我试过了,还是不行:/
  • 您是否尝试过调用 super.saveState() 而不是返回 null。
  • 如果我这样做,当我第二次打开片段时应用程序崩溃并出现此错误:java.lang.IllegalStateException: Fragment no longer exists for key f0: index 0
  • 能否请您发布整个异常日志?我认为这就是奇怪行为的原因。我也遇到过类似的问题,去掉这个就行了

标签: android android-fragments fragmentstatepageradapter


【解决方案1】:

我几周前遇到过这个问题,并且总是在 FragmentStatePagerAdapter 中的 saveState() 或 restoreState() 有一些错误,所以我明白你为什么试图在 saveState() 中返回 null。

首先我建议您使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter,并将其添加到您的适配器中:

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

如果它不适合您,也许您想创建自己的 PageAdapter,直接从 PageAdapter 继承,并将 FragmentPagerAdapter 的代码复制到您的 PageAdapter 中。如果你坚持使用restoreState()和saveState(),只要按照FragmentStatePagerAdapter调试即可。

这可能看起来很麻烦,但是在我实现了我的 PageAdapter 之后,我永远不会害怕任何关于 viewpage + fragment 的问题。

【讨论】:

    【解决方案2】:

    我也面临同样的问题,我通过更改 fragmentAdapter 和父片段中的某些点来修复。

    1. 首先检查您在 FriendsTabsPagerAdapter 中扩展 FragmentPagerAdapter。
    2. 当您创建 FriendsTabsPagerAdapter 对象时,您必须传递 getChildFragmentManager() 方法而不是 getActivity().getSupportFragmentManager()。

    我只更改了这两点,任何片段都可以正常工作。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,请使用以下代码。

      public class FriendsTabsPagerAdapter extends FragmentPagerAdapter {
      
          // 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;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-06
        相关资源
        最近更新 更多