FragmentPagerAdaper中的RecyclerView仅在旋转屏幕时更新

时间:2015-06-17 11:37:17

标签: android android-fragments android-recyclerview fragmentpageradapter

我在FragmentPagerAdpater中有一个片段。 Fragment基本上是RecyclerView。 RecyclerView的源代码由Fragment内的Loader提供。

我的问题是首次实例化时列表显示为空。但是当我旋转屏幕时,它显得很好。

你知道可能出现什么问题吗? 如果需要,我很乐意提供一些(或很多)代码。告诉我你想看到哪些部分。

以下是父活动的代码:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
            case 0:
                //We return an instance of the RouteListFragment
                RouteListFragment frag = RouteListFragment.getInstance(session.getId());
                return frag;
            case 1:
                //We return an instance of the RouteSpotListFragment
                RouteSpotListFragment frag2 = RouteSpotListFragment.getInstance(sessionSpot.getId());
                return frag2;
            default :
                return null;
        }

    }

Fragment的主要方法:

public static RouteListFragment getInstance (int sessionId){
    RouteListFragment frag = new RouteListFragment();
    Bundle bundle = new Bundle ();
    bundle.putInt(SESSION_ID, sessionId);
    frag.setArguments(bundle);
    return frag;
}

/* (non-Javadoc)
 * @see android.app.Fragment#onCreate(android.os.Bundle)
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    //We extract the RouteList from the Bundle
    Bundle bundle = getArguments();
    sessionId = bundle.getInt(SESSION_ID);

    //We create a MyRouteListAdapter with a null cursor
    Cursor cursor = null;
    routeListAdapter = new MyRouteListAdapter(cursor, getActivity());
    updateList();

    super.onCreate(savedInstanceState);
}

/* (non-Javadoc)
 * @see android.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    //Inflate the layout
    layout = (RelativeLayout) inflater.inflate(R.layout.fragment_route_list, container, false);

    routeSource = new RouteDataSource (getActivity());

    //Now that we have the routeSource, we can prepare the routeListAdapter
    routeRecyclerList = (RecyclerView) layout.findViewById(R.id.route_list_view);
     // use a linear layout manager
    mLayoutManager = new LinearLayoutManager(getActivity());
    routeRecyclerList.setLayoutManager(mLayoutManager);

    routeRecyclerList.setAdapter(routeListAdapter);

    return layout;
}

    public void updateList(){
    /*
     * we get the loaderManager to start the query
     * If a Loader has already been initiated, we need to reload it. Otherwise the 
     * onCreateLoader callback method will not be called
     * Else, we initiate a Loader
     */
    LoaderManager manager = getLoaderManager();
    if (manager.getLoader(LOADER_GET_ALL_ROUTES)!= null)    
        manager.restartLoader(LOADER_GET_ALL_ROUTES, null, this);
    else manager.initLoader(LOADER_GET_ALL_ROUTES, null, this);

}

最后,我将onLoadFinished()回调方法中的游标交换为LoaderManager.Callback方法的一部分。

编辑:我刚刚意识到,如果我等待LoaderManager完成加载(1-2秒),则在滑动包含Loader的Fragment之前,会显示内容。

我不知道新信息是否会改变任何内容。我仍然非常困难,肯定需要帮助。

2 个答案:

答案 0 :(得分:3)

我终于解决了我的问题,这是如何:

1 - 将FragmentPagerAdapter更改为FragmentStatePagerAdapter。原因是FragmentPagerAdapter在需要时不会重新创建碎片。它将一切都记在内存中。因此,如果您的片段在创建时未完全正常运行,或者您希望稍后再刷新它,则会遇到麻烦。

2 - 从Fragments中删除LoaderManager结构,让父Activity处理查询数据库。这样,我可以让FragmentStatePagerAdapter首先实例化一个空片段,然后活动可以告诉适配器在查询返回后重新创建片段。为了重新创造,我需要FragmentStatePagerAdapter

3 - 覆盖我的FragmentStatePagerAdapter的getItemPosition(),以便在PagerAdapter上调用notifyDataSetChanged()时重新创建所有片段:

public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

因为我的片段不是太复杂而且要加载的数据不是很大,所以我不介意重新创建我拥有的所有片段。因此,使用POSITION_NONE是明智的。

我希望这些小小的发现可以帮助其他人。 =)

答案 1 :(得分:1)

super.onCreate(savedInstanceState)移至第一行......

  

为什么会有效??

在您的代码中,您已将super.onCreate()放在方法的末尾。并且您已经首先应用了您的代码。所以你强迫android停止它们的默认实现onCreate()这是不好的。 因为在他们的方法中他们正在进行所有初始化和UI相关的任务

因此,最好始终在第一行拨打super()

我希望你理解。