【问题标题】:How to update data from database in near standing Fragments in ViewPager如何在 ViewPager 中的近站片段中更新数据库中的数据
【发布时间】:2014-09-07 19:37:08
【问题描述】:

首先我想说,我对 Android 开发和编程真的很陌生,我尝试做一些我不完全理解的事情,因为,如果不是这样,那如何学习呢? (例如使用 CursorLoader 而不是已弃用的 startManagingCursor)。其次,我正在使用自定义库click. 它很棒且易于使用。现在我将尝试描述我的问题。
我在我的 CustomPagerAdapter 中添加了 3 个单独的片段。

private static class CustomPagerAdapter extends FragmentPagerAdapter
            implements  SlidingTabLayoutColor.ColorProvider, SlidingTabLayoutColor.ImageProvider {
    ArrayList<Fragment> fragments;
    public CustomPagerAdapter(FragmentManager fm) {
            super(fm);
            fragments = new ArrayList<Fragment>();
            fragments.add(new FragmentAll());
            fragments.add(new FragmentFav());
            fragments.add(new FragmentNotFav());
    }
}

在每个片段中,我都有 ListView,其中包含来自数据库的记录,我可以使用 contextmenu 删除它们(通过单独的 Activity 添加记录)。

public boolean onContextItemSelected(MenuItem item) {
        if (item.getItemId() == 1) {
            AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
            db.delRec(acmi.id);
            getLoaderManager().getLoader(0).forceLoad();
            return true;
        }
        return super.onContextItemSelected(item);
}

问题是当我从一个 Fragment 中删除记录并滑动到下一个 Fragment 时,第二个 Fragment 不会更新 ListView 并且会显示已删除的旧记录。在这种情况下,生命周期对我没有帮助,因为当你刷两个靠近站立的片段时没有任何反应。该库的作者建议我重写 onPageSelected 方法,但我不明白如何从 Activity 更新 Fragment 中的 ListView。我在 stackoverflow 上阅读了很多相同的问题,但没有找到适用于 CursorLoader 的合适解决方案。在每个 Fragment 的 onCreateView 我过去了这个:

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

我还重写了这些方法并创建了 MyCursorLoader 类:

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
        return new MyCursorLoader(getActivity(), db);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        scAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {

    }

     static class MyCursorLoader extends CursorLoader {

        DB db;

        public MyCursorLoader(Context context, DB db) {
            super(context);
            this.db = db;
        }

        @Override
        public Cursor loadInBackground() {
            Cursor cursor = db.getAllData();
            return cursor;
        }
    }

我尝试在 Fragment 中创建这样的方法:

public void refreshData() {
        getLoaderManager().getLoader(0).forceLoad();
}

并从 onPageSelected 调用它:

@Override
public void onPageSelected(int i) {
    FragmentAll fragmentAll = new FragmentAll();
    if (i == 0) {
        fragmentAll.refreshData();
    }
}

但这导致了一个错误。请帮我解决我的问题,不要忘记我是初学者。 ;) 感谢您的关注!

【问题讨论】:

    标签: android android-fragments android-listview android-viewpager android-cursorloader


    【解决方案1】:

    我认为问题出在:

    @Override
    public void onPageSelected(int i) {
        FragmentAll fragmentAll = new FragmentAll();
        if (i == 0) {
            fragmentAll.refreshData();
        }
    }
    

    每次选择位置 0 处的页面时,您都会创建一个 FragmentAll 的新实例,而不是在您添加到 CustomPagerAdapter 中的原始片段上调用 ​​refreshData

    所以你应该在这里做的是获取原始片段的实例,并在数据更新时调用refreshData,即在OnContextItemSelected内部。你可以这样做,我在你的Activity 中创建一个方法respond 来承载ViewPager

    public void respond() {
        ((FragmentAll) customPagerAdapter.fragments.get(0)).refreshData();
        ((FragmentFav) customPagerAdapter.fragments.get(1)).refreshData();
        ((FragmentNotFav) customPagerAdapter.fragments.get(2)).refreshData();
    }
    

    这就是你的OnContextItemSelected 的样子:

    public boolean onContextItemSelected(MenuItem item) {
            if (item.getItemId() == 1) {
                AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
                db.delRec(acmi.id);
                //getLoaderManager().getLoader(0).forceLoad();
                ((NameOfYourActivityThatHostsViewPager) getActivity()).respond();
                return true;
            }
            return super.onContextItemSelected(item);
    }
    

    请注意,这要求您在所有片段(All、Fav 和 NotFav)中都有 refreshData 方法。

    我希望这能解决您的问题。

    【讨论】:

    • 效果很好,当我已经刷过所有 3 个片段时,但如果我只是加载我的应用程序而不刷第三个片段,并尝试删除记录,则会抛出 IllegalStateException: Fragment FragmentNotFav 未附加到 Activity,如何将其附加到应用加载中?
    • 你可以通过调用isAdded来检查一个fragment是否已经附加到它的activity上如果返回true,那么你可以继续调用refreshData
    • 感谢您的快速回答,我尝试在 null 上检查片段,当然它不起作用;)我对片段真的很陌生;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多