【问题标题】:ListView of a Fragment (of a ViewPager inside a Fragment) that implements LoaderCallbacks<Cursor> is empty when I return back to it当我返回它时,实现 Loader Callbacks<Cursor> 的片段的 ListView(片段内的 ViewPager)为空
【发布时间】:2017-05-19 13:08:19
【问题描述】:

当我返回时,包含 ViewPager 的 Fragment 内部的 ListView 是空的。此 ViewPager 位于 Fragment 内部,因为我使用的是导航抽屉布局。我现在将尝试更详细地解释它:

我正在使用导航抽屉布局,因此使用片段。在主要活动中,在 onCreate 中,我使用以下代码行设置了当前 Fragment:

@Override
protected void onCreate(Bundle savedInstanceState) {

    /* More code */

    currentFragment = new MainFragment();
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();
}

MainFragment 类包含一个 ViewPager,它使用 onCreateView() 中的这些代码行进行初始化:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    /* More code */

    ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.main_view_pager);
    viewPager.setAdapter(new SimpleFragmentPagerAdapter(getActivity(), getActivity().getSupportFragmentManager()));

    /* Code for Tablayout */

    return rootView;
}

SimpleFragmentPagerAdapter 类的 Fragments 之一就是实现了 LoaderManager.LoaderCallbacks 的这个

public class ExpensesFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private ExpenseCursorAdapter mExpenseCursorAdapter;

    private static final int EXPENSE_LOADER = 1;

    public ExpensesFragment() {
        // Required empty public constructor
    }

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

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

        ListView expensesListView = (ListView) rootView.findViewById(R.id.expenses_list_view);
        mExpenseCursorAdapter = new ExpenseCursorAdapter(getContext(), null);
        expensesListView.setAdapter(mExpenseCursorAdapter);

        getLoaderManager().initLoader(EXPENSE_LOADER, null, this);

        return rootView;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(/* arguments */);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mExpenseCursorAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mExpenseCursorAdapter.swapCursor(null);
    }
}

在第一次运行时,一切正常。但是,如果我单击以这种方式实现的导航抽屉菜单,则 ListView 变为空:

public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.nav_main) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().remove(currentFragment).commit();

        currentFragment = new MainFragment();
        fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();

    } else if (id == R.id.nav_blank) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().remove(currentFragment).commit();

        currentFragment = new BlankFragment();
        fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();

    }

    drawer.closeDrawer(GravityCompat.START);
    return true;
}

旋转设备时也存在问题。不过还是有区别的。当我使用导航抽屉菜单时,没有调用 LoaderManager.LoaderCallbacks 的任何方法,但是当我旋转设备时,会调用 onLoadFinished。

无论如何,问题仍然存在。任何想法如何解决它?

提前致谢。

【问题讨论】:

    标签: java android listview android-fragments loader


    【解决方案1】:

    我找到了解决办法!

    基本上,我犯了两个错误。 第一个是关于设备的旋转。 当设备旋转时,Activity被销毁并再次调用onCreate。在这种情况下,我不应该调用 new MainFragment()。所以,我在调用它之前检查 savedInstanceState 是否为空,如下所示:

    if (savedInstanceState == null) {
        currentFragment = new MainFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().
                replace(R.id.layout_for_fragments, currentFragment).commit();
    }
    

    第二个是关于片段中的片段。在这种情况下,我不能简单地调用 getSupportFragmentManager()。我应该调用 getChildFragmentManager() 来代替,就是这样!

    【讨论】:

      猜你喜欢
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      相关资源
      最近更新 更多