Java 当ListFragment从后堆栈返回布局时,如何刷新它?

Java 当ListFragment从后堆栈返回布局时,如何刷新它?,java,android,listview,actionbarsherlock,android-support-library,Java,Android,Listview,Actionbarsherlock,Android Support Library,首先,我应该提到,我正在使用ActionBarSherlock库实现向后兼容性 我有一个活动,它在第一次启动时添加了一个ListFragment。我有一个定制的加载器,我实现了它,并非常严格地遵循了。MyListFragment实现了LoaderCallbacks接口。添加片段(onCreateLoader(),onLoaderFinished())和替换片段(onLoaderReset())时,将调用所有适当的回调方法 我的onActivityCreated(Bundle)方法如下所示: @O

首先,我应该提到,我正在使用ActionBarSherlock库实现向后兼容性

我有一个活动,它在第一次启动时添加了一个
ListFragment
。我有一个定制的
加载器
,我实现了它,并非常严格地遵循了。My
ListFragment
实现了
LoaderCallbacks
接口。添加片段(
onCreateLoader()
onLoaderFinished()
)和替换片段(
onLoaderReset()
)时,将调用所有适当的回调方法

我的
onActivityCreated(Bundle)
方法如下所示:

@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);
}
稍后,
ListFragment
被另一个片段B替换。 当用户按下后退按钮时,片段B被删除,ListFragment被再次添加。但是,列表为空,仅显示
android:empty
元素,并且不调用LoaderCallback方法。我可以使用调试器确定
getLoaderManager().initLoader(0,null,this),但没有其他调用。
当我将其更改为
getLoaderManager().restartLoader(0,null,this)时,将调用回调,但我的列表仍然为空(尽管有数据,但视图不会刷新)

当ListFragment返回到布局时,如何让它刷新自身? 以前是否有人遇到过这种情况,您是如何解决的

仅供参考,以下是我的回调方法

    @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);
}
@覆盖
公共加载器onCreateLoader(int-id,Bundle-args){
返回新的AccountsCursorLoader(this.getActivity()
.getApplicationContext());
}
@凌驾
public void onLoadFinished(加载器加载器游标,光标){
mCursorAdapter.swapCursor(光标);
mCursorAdapter.notifyDataSetChanged();
}
@凌驾
公共void onLoaderReset(加载程序arg0){
mCursorAdapter.swapCursor(空);
}
一些注意事项:

  • 我无法在示例中使用
    setlistshighed(true)
    方法,因为我得到了一个
    IllegalStateException
    ,它不能与自定义内容视图一起使用
  • My
    AccountsCorsorAdapter
    扩展了一个
    SimpleCorsorAdapter
    并仅修改
    bindView()
    方法

  • 在我的例子中,我发现由于某种原因,ListView并没有被绘制在屏幕上。如果我转到主屏幕,然后切换回活动,所有内容都会按预期显示。因此,我搜索了一种方法来强制重新绘制屏幕,结果发现:

    根据对该问题的回答,我将以下代码添加到我的ListFragment的
    onActivityCreated()
    方法中:

    getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 0);
    
    有了这段代码,一切都按预期进行。但这仍然是一个解决办法,因此如果有人用更好的解决方案或解释来回答这个问题,我将奖励他们。

    试试:


    问题可能来自
    getLoaderManager()
    ,它不会将回调发送到正确的位置

    如果你使用的是ActionBarSherlock,那就意味着你使用的是Android 2.x,对吗?您是否考虑过使用Android支持包v4


    然后,您将使用
    android.support.v4.app.ListFragment
    ,并通过调用
    getActivity().getSupportLoaderManager()
    获取您的
    LoaderManager,因为您使用的是自定义加载程序,您知道在使用本机游标加载程序时是否存在相同的问题吗?如果没有,那么也许你可以将你的加载器与Android源代码进行比较,看看他们是否做了一些不同的事情

    万岁!!!我找到了它(当然是偶然的)

    TL;博士

    在中,我现在在
    onCreate()
    方法中创建我的数据库适配器(
    AccountsDatabaseAdapter
    ),并在
    onDestroy()
    方法中关闭它,它现在可以工作了。之前,我在ActivityCreated()上创建适配器,并在onDestroyView()上关闭。请注意,我指的不是
    ListAdapter
    ,而是我的数据库接口
    AccountsDbAdapter

    尝试详细解释:

    我这样做是因为我认为在
    onCreate()
    方法中不可能通过
    getActivity()
    获取上下文。事实证明,甚至在调用onActivityCreated()
    之前,您就可以
    getActivity()

    但是我无法解释为什么现在可以这样做,因为
    加载程序
    有自己的
    数据库适配器
    对象,它使用该对象来检索数据。如果我猜的话,我会说为两个数据库适配器()返回相同的数据库对象。这意味着当我在
    onDestroyView()
    中关闭一个时,另一个也会关闭,光标数据集将无效,从而导致空列表视图。加载程序不重新加载,因为它认为数据没有更改

    但即使是这样的解释也不能完全满足我,因为我在这里尝试的一些建议解决方案,比如每次强制重新启动装载机,都不起作用。(在
    loadInBackground()
    方法中,每次都会创建一个新的
    DatabaseAdapter

    不管怎样,如果你碰巧对正在发生的事情有了更好的理解,请在评论中反复强调


    谢谢大家的帮助

    您是否尝试在活动中强制加载程序重新启动, 在基础数据集更改之后

    尝试:

    适配器看到的内容: 观察空ListView的原因是返回的光标位置仍然指向最后一个元素。当您
    swap()
    将光标切换到适配器时,适配器尝试使用
    while(Cursor.moveToNext())
    循环进行迭代。因为这个循环总是计算F
    getLoaderManager().getLoader( 0 ).forceLoad();
    
    getLoaderManager().restartLoader(0, null, this);