我怎样才能刷新我的ListFragment的时候才返回从后堆栈的布局? [英] How can I refresh my ListFragment when it returns to the layout from back stack?

查看:201
本文介绍了我怎样才能刷新我的ListFragment的时候才返回从后堆栈的布局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我要指出,我使用向后兼容的ActionBarSherlock库。

我增加了一个 ListFragment 首次启动时的活动。我有一个自定义的装载机这是我实现并符合 AsnycTaskLoader例如的非常紧密。我的 ListFragment 实施 LoaderCallbacks<光标> 接口。所有适当的回调方法被调用时,片段被添加( onCreateLoader() onLoaderFinished()),并且当被替换( onLoaderReset())。

我的 onActivityCreated(捆绑)的方法是这样的:

  @覆盖
公共无效onActivityCreated(包savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    mAccountsDbAdapter =新AccountsDbAdapter(getActivity()getApplicationContext());

    setHasOptionsMenu(真正的);
    mCursorAdapter =新AccountsCursorAdapter(getActivity()
            .getApplicationContext(),R.layout.list_item_account,空,
            新的String [] {} DatabaseHelper.KEY_NAME,
            新INT [] {R.id.account_name},0);

    setListAdapter(mCursorAdapter);
    getLoaderManager()initLoader(0,空,这一点)。
}
 

后来, ListFragment 被替换为另一个片段B. 当用户presses返回按钮,片段B被去除,ListFragment再次添加。不过,该列表是空的,只有 Android版本:空元素都显示出来,并没有一个LoaderCallback方法被调用。我可以使用调试器来确定 getLoaderManager()initLoader(0,空,这一点); 实际上是调用,但没有别的。 当我将其更改为 getLoaderManager()restartLoader(0,空,这一点); ,回调被调用,但是还是我的列表是空的(虽然有数据显示,视图不刷新)。

我怎样才能让我的ListFragment刷新自己,当它返回到布局? 有没有人遇到过这一点,你是怎么解决的呢?

仅供参考,这里有我的回调方法

  @覆盖
公共装载机<光标> onCreateLoader(INT ID,捆绑参数){
    返回新AccountsCursorLoader(this.getActivity()
            .getApplicationContext());
}

@覆盖
公共无效onLoadFinished(装载机<光标> loaderCursor,光标光标){
    mCursorAdapter.swapCursor(光标);
    mCursorAdapter.notifyDataSetChanged();
}

@覆盖
公共无效onLoaderReset(装载机<光标>为arg0){
    mCursorAdapter.swapCursor(空);
}
 

一些注意事项:

  1. 在我无法使用 setListShown(真)方法的例子,因为我得到一个 IllegalStateException异常,它不能使用自定义内容视图中使用。
  2. 在我的 AccountsCursorAdapter 扩展了 SimpleCursorAdapter 键,仅修改 bindView()方法。
解决方案

尤里卡!我发现它(偶然,当然)

TL; DR;

AccountsListFragment ,现在我创造我的数据库适配器( AccountsDatabaseAdapter )的的onCreate()方法,并关闭它在的onDestroy()方法,它现在的作品。 previously我创建我的适配器中的 onActivityCreated()和关闭 onDestroyView()。请注意,我不是指 ListAdapter ,而是我的数据库接口 AccountsDbAdapter

尝试在漫长的解释:

唉,我这样做,因为我觉得通过 getActivity获取上下文()将无法在的onCreate()方法。事实证明,你可以 getActivity()之前 onActivityCreated()被调用。

但我真的不能解释为什么现在这个工作,因为装载机都有自己的 DatabaseAdapter 对象,它用来检索数据。如果我猜,我会说,同一个数据库对象返回为数据库适配器(<一href="http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase%28%29"相对=nofollow>数据库缓存)。这意味着,当我关闭一个在 onDestroyView(),另外也将关闭,光标数据集变得无效从而导致空列表视图。装载机不会重新加载,因为它认为该数据并没有改变。

但是,即使这样的解释并不能满足我彻底,因为这里的一些建议的解决方案,我试着像力重新加载每次没有工作的。 (在 loadInBackground()的方法,新的 DatabaseAdapter 每次创建)。

无论如何,如果你碰巧有一个更好的理解到底是怎么回事,请锤离开的意见。

感谢大家的帮助,这一点!

First I should mention that I am using the ActionBarSherlock library for backwards compatibility.

I have an activity which adds a ListFragment when it is first started. I have a custom Loader which I implemented and follows the AsnycTaskLoader example very closely. My ListFragment implements the LoaderCallbacks<Cursor> interface. All the appropriate callback methods are called when the fragment is added (onCreateLoader() , onLoaderFinished() ) and when it is replaced (onLoaderReset() ).

My onActivityCreated(Bundle) method looks like this:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mAccountsDbAdapter = new AccountsDbAdapter(getActivity().getApplicationContext());

    setHasOptionsMenu(true);
    mCursorAdapter = new AccountsCursorAdapter(getActivity()
            .getApplicationContext(), R.layout.list_item_account, null,
            new String[] { DatabaseHelper.KEY_NAME },
            new int[] { R.id.account_name }, 0);

    setListAdapter(mCursorAdapter); 
    getLoaderManager().initLoader(0, null, this);
}

Later on, the ListFragment is replaced with another Fragment B. When the user presses the back button, Fragment B is removed and the ListFragment is added again. However, the list is empty and only the android:empty elements are displayed and none of the LoaderCallback methods are called. I can use the debugger to determine that getLoaderManager().initLoader(0, null, this); is actually called, but nothing else. When I change it to getLoaderManager().restartLoader(0, null, this);, the callbacks get called, but still my list remains empty (although there is data, the view is not refreshed).

How can I get my ListFragment to refresh itself when it is returned to the layout? Has anyone encountered this before, how did you fix it?

FYI, here are my callback methods

    @Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    return new AccountsCursorLoader(this.getActivity()
            .getApplicationContext());
}

@Override
public void onLoadFinished(Loader<Cursor> loaderCursor, Cursor cursor) {
    mCursorAdapter.swapCursor(cursor);
    mCursorAdapter.notifyDataSetChanged();
}

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

Some notes:

  1. I cannot use the setListShown(true) methods in the example because I get an IllegalStateException that it cannot be used with a custom content view.
  2. My AccountsCursorAdapter extends a SimpleCursorAdapter and modifies only the bindView() method.

解决方案

Eureka!!! I found it (by accident, of course)

TL;DR;

In the AccountsListFragment, I now create my database adapter (AccountsDatabaseAdapter) in the onCreate() method and close it in the onDestroy() method and it now works. Previously I was creating my adapter in the onActivityCreated() and closing in onDestroyView(). Note that I am not referring to the ListAdapter, but rather to my database interfacing AccountsDbAdapter.

Attempt at long explanation:

Well, I was doing this because I thought that getting context through getActivity() will not be possible in the onCreate() method. It turns out you can getActivity() even before onActivityCreated() is called.

But I cannot really explain why this now works because the Loader has its own DatabaseAdapter object which it uses to retrieve the data. If I were to guess, I would say that the same database object is returned for both database adapters (the database is cached). Which would mean that when I close one in onDestroyView(), the other is also closed and the cursor data set becomes invalid which results in an empty list view. The loader does not reload because it thinks the data has not changed.

But even this explanation does not satisfy me completely, because some of the suggested solutions here which I tried like force restarting the loader each time did not work. (in the loadInBackground() method, a new DatabaseAdapter is created each time).

Anyway, if you happen to have a better understanding of what is going on, please hammer away in the comments.

Thanks everyone for the help with this!

这篇关于我怎样才能刷新我的ListFragment的时候才返回从后堆栈的布局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆