在常规(支持)片段中使用 AsyncTaskLoader 更新适配器不更新 ListView

Posted

技术标签:

【中文标题】在常规(支持)片段中使用 AsyncTaskLoader 更新适配器不更新 ListView【英文标题】:Updating adapter with AsyncTaskLoader in a regular (support) Fragment not updating ListView 【发布时间】:2015-02-20 09:04:37 【问题描述】:

我在使用AsyncTaskLoader 回调更新常规Fragment 中的适配器时遇到问题。我正在使用片段支持库,版本 19.1.0。

在我的onLoadFinished() 回调中,我只需执行mAdapter.addAll(data)。我使用调试器来验证回调是否被调用,并且所有数据都已添加到适配器中。问题是列表视图根本不会更新。

我已经尝试过notifyDataSetChanged()invalidateViews() - 没有效果。

到目前为止,我看到的所有示例或教程都使用 ListFragmentListActivity 没有自定义布局;我已经尝试过了,它工作正常。特别是,我尝试了来自android Design Patterns loader tutorial 的示例程序。不幸的是,我不能使用ListFragment,因为我正在使用StickyListHeaders 库(但即使尝试使用常规ListView 也不起作用)。

在修改above sample program 以使用Fragment 而不是ListFragment 通过删除ListFragment 特定的方法调用并扩展自定义视图时,我得到了相同的结果。相关代码归结为:

@Override
public void onActivityCreated(Bundle savedInstanceState) 
    super.onActivityCreated(savedInstanceState);
    mAdapter = new AppListAdapter(getActivity());
    getLoaderManager().initLoader(LOADER_ID, null, this);


@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    final View v = inflater.inflate(R.layout.list_layout, container, false);
    ListView listView = (ListView) v.findViewById(android.R.id.list);
    listView.setAdapter(mAdapter);
    return v;


@Override
public void onLoadFinished(Loader<List<AppEntry>> loader, List<AppEntry> data) 
    mAdapter.setData(data);

正如我之前所说,适配器会更新,但列表视图根本不会重绘,即使您添加 notifyDataSetChanged 并在 listView 上调用 invalidateViews 也是如此。我发现很难弄清楚这里出了什么问题。

【问题讨论】:

你的适配器代码是什么? 确实,我们需要查看您的适配器代码 - 如果视图没有更新,那么适配器很可能是罪魁祸首。 澄清一下,我的意思是 ListView 保持空白,并且没有显示适配器中的任何项目。上面示例中使用的适配器代码可以在here 找到。我正在开发的实际应用程序的适配器代码可以在 here 找到。 【参考方案1】:

原来问题是在onActivityCreated 中初始化适配器,因为它被称为之后 onCreateView - 所以setAdapter 被传递了一个空值(它不会抱怨那)。这在我查看的ListFragmentListActivity 实现中不是问题,因为您可以使用他们的setListAdapter 方法将适配器与列表视图相关联,而无需保留您自己对它的显式引用。一个愚蠢的错误:\

【讨论】:

【参考方案2】:

我以前也遇到过类似的问题。我的根似乎没有从 ui 线程调用 notifyDataSetChanged。你的问题可能类似,试试:

yourContext.runOnUiThread(new Runnable() 
    public void run() 
        mAdapter.notifyDataSetChanged();
    
);

如果它适合你,请告诉我。

【讨论】:

行为没有改变,ListView 仍然没有显示任何内容。我相信应该在 UI 线程上调用 LoaderManager 回调。 嗯,也许尝试将大部分列表视图逻辑放在 ui 线程中。您能否将您的适配器代码复制粘贴到问题编辑中?

以上是关于在常规(支持)片段中使用 AsyncTaskLoader 更新适配器不更新 ListView的主要内容,如果未能解决你的问题,请参考以下文章

在片段中裁剪图像

Android:使用支持片段管理器时复制片段

片段还是支持片段?

如何使用支持库 25.0.0 及更高版本获取片段()

从片段显示对话框?

nestjs 是不是支持 graphql 片段?