刷新 ArrayAdapter onResume [notifyDataSetChanged() 不工作]

Posted

技术标签:

【中文标题】刷新 ArrayAdapter onResume [notifyDataSetChanged() 不工作]【英文标题】:Refreshing ArrayAdapter onResume [notifyDataSetChanged() not working] 【发布时间】:2013-04-19 15:24:01 【问题描述】:

我正在使用 Fragments 创建一个联系人列表应用程序,其中一个片段是联系人列表中的姓名列表,另一个是其余详细信息。

这是显示名称列表的类

public class MyListFragment extends ListFragment 

private ContactStorage contactStorage = new ContactStorage();

public final static String TAG = "FRAGMENTS";
private MainActivity parent;
ArrayAdapter<String> adapter;

ArrayList<String> entries = new ArrayList<String>();

String array[];

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

    View v = inflater.inflate(R.layout.list_layout, null);
    parent = (MainActivity) getActivity();
    entries = contactStorage.getContactListNames();

    adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(), 
            android.R.layout.simple_list_item_1, entries);

    setListAdapter(adapter);
    Log.d(TAG, "Adapter created");
    array = contactStorage.getContactDetails();
    return v;



@Override
public void onResume() 

    super.onResume();
    entries = contactStorage.getContactListNames();
    adapter.notifyDataSetChanged();
    Log.d(TAG, "List Frag Resumed");



我遇到的问题是 ArrayAdapter 在恢复时没有刷新。

当屏幕旋转时,它可以再次运行 onCreateView(),但我需要它来刷新 onResume。我查看了这个网站的加载情况,除了“使用 notifyDataSetChanged()”之外什么也没发现。

【问题讨论】:

好吧,你期待什么?您正在检索 entries 但 aret re-building your adapter. Move the two lines entires =` 和 adapter =onCreate()onResume() (你应该只这样做一次),忘记 entries =notifyonResume(),你会没事的。 @ClassStacker - 还是同样的问题。在屏幕旋转之前不刷新列表。 嗯,是的,抱歉,您还必须在那里执行 setListAdapter()。 @ClassStacker - 我可以看到它是如何工作的,但这会更像是一种“hacky”方式吗? 我的建议和你接受的一样。它没有什么“hacky”。只是clear()/addAll()的方法比直接扔掉整个en bloc要慢。 【参考方案1】:

您遇到的问题是您正在覆盖条目引用并且它没有在适配器上发生更改。以下是解决此问题的方法

@Override
public void onResume() 

    super.onResume();
    entries.clear();
    entries.addAll(contactStorage.getContactListNames());
    adapter.notifyDataSetChanged();
    Log.d(TAG, "List Frag Resumed");


这是一个常见的错误,这是因为当您第一次创建一个列表(在内存中)并且您的 entries 字段指向该列表时,然后您告诉 adapter 在创建时查看该内存位置它,但是onResume 您在内存中创建了一个新列表(当您再次获取联系人列表名称时)并告诉条目指向内存中的新列表,您需要做的是将原始列表中的条目替换为新列表中的条目,这样adapter 仍将引用相同的列表。

【讨论】:

完美!我知道与“.add()”有关,但我无法得到关于该主题的明确答案。非常感谢! 我也添加了关于该问题的更好解释。您可以使用 ArrayAdapter 执行此操作的另一种方法是简历 adapter.clear(); 然后 adapter.addAll(contactStorage.getContactListNames()); 并一起忘记条目字段。 清除列表并再次添加更新的元素会在最新的 android 中引发 ConcurrentModificationException,因为 ArrayAdapter 也在尝试读取列表。 Clear Adapter 和 adapter.addAll() 工作正常。荣誉@Eluvatar【参考方案2】:

notifyDataSetChanged() 对您不起作用。原因

您的适配器丢失了对您列表的引用。当您第一次初始化 Adapter 时,它会引用您的 arrayList 并传递给它的超类。但是,如果您重新初始化现有的 arrayList,它会丢失引用,因此会丢失与 Adapter 的通信通道 :(.

始终创建新列表并将其添加到适配器。这样做:

    在全局声明时初始化arrayList。 直接将列表添加到适配器,而不检查 null 和 empty 健康)状况。直接将适配器设置到列表中(不检查任何 健康)状况)。适配器为您提供保证,无论您身在何处 更改它会处理的 arrayList 的数据,但永远不要丢失 参考。 每次都向arrayList添加数据(如果你的数据是全新的 比你之前可以调用 adapter.clear() 和 arrayList.clear() 实际上将数据添加到列表中)但不设置适配器,即如果 新数据填充在 arrayList 中,而不仅仅是 adapter.notifyDataSetChanged()

对文档保持信任

【讨论】:

以上是关于刷新 ArrayAdapter onResume [notifyDataSetChanged() 不工作]的主要内容,如果未能解决你的问题,请参考以下文章

我的 onResume 依赖于`onViewCreated`。我该如何重新设计它?

android activity间通讯,跳转回主activity时总会刷新怎么办?

AsyncTask 不断重复 onResume

Fragment-Fragment切换的数据刷新问题

Android:从 ListView/ArrayAdapter Activity 中删除项目

Cordova 没有触发 OnResume 功能 iOS