在 Android 上刷新 Adapter/ListView 的最佳方式

Posted

技术标签:

【中文标题】在 Android 上刷新 Adapter/ListView 的最佳方式【英文标题】:Best Way to Refresh Adapter/ListView on Android 【发布时间】:2011-05-10 19:07:20 【问题描述】:

我的书“Hello android”提供了一种使用自定义数据库助手、设置光标、然后设置适配器的方法,如下所示:

Cursor cursor
CustomDatabaseHelper test = new CustomDatabaseHelper(this);
try 
        cursor = getData();
        showData(cursor);
 finally 
        test.close();

但是,有了这个,每次我需要刷新数据集时,我都需要继续运行这段代码(由于“this”不可用,这在按钮的 onClick() 中变得有点困难。

这是刷新数据集的最佳方式,还是我应该考虑删除 .close 并发出 adapter.notifyDataSetChanged()?如果我这样做,有时我会强制关闭(我现在不记得了)但有时它无法正确删除 - 我认为这可能是因为数据库当前已打开并且它试图再次打开。

我们是否也应该在类中(在 OnCreate 之外)声明 Cursors、DatabaseHelpers 和 Adapter 的变量,以便所有函数都可以访问它们?

我意识到在这个阶段这只是糟糕的编程,但我试图获得一些关于最好的做事方式的指针。

【问题讨论】:

只是一个旁注:如果您使用内容提供程序和 LoaderManager,情况会有所不同。见:***.com/a/19657500/1087411 【参考方案1】:

您应该使用adapter.notifyDataSetChanged()。当你使用它时,日志会说什么?

【讨论】:

谢谢 Macarse,这确实有效,但前提是我不对数据库助手执行 .close 操作。我认为如果我不执行 .close 会发生什么,系统会尝试打开太多数据库并崩溃。那么数据库是否应该在活动的整个生命周期中打开? 你应该使用developer.android.com/reference/android/app/…来管理你在Activity中的光标。【参考方案2】:

以下代码非常适合我

EfficientAdapter adp = (EfficientAdapter) QuickList.getAdapter();
adp.UpdateDataList(EfficientAdapter.MY_DATA);
adp.notifyDataSetChanged();
QuickList.invalidateViews();
QuickList.scrollBy(0, 0);

【讨论】:

调用 notifyDataSetChanged() 对我来说还不够。 invalidateViews() 反而有效。【参考方案3】:

只需在设置 Adapter 之前添加这些代码即可:

    listView.destroyDrawingCache();
    listView.setVisibility(ListView.INVISIBLE);
    listView.setVisibility(ListView.VISIBLE);

或者直接在更改数据资源后使用下面的方法。

   adapter.notifyDataSetChanged()

【讨论】:

这也适用于按钮: // 强制刷新 myButton.setVisibility(Button.INVISIBLE); myButton.setVisibility(Button.VISIBLE); 刷新按钮的目的是什么? 在过滤器之后,然后应用其反向。【参考方案4】:

如果您正在使用 LoaderManager,请尝试以下语句:

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

【讨论】:

【参考方案5】:

只需在您的自定义 ArrayAdaper 中写入以下代码:

public void swapItems(ArrayList<Item> arrayList) 
    this.clear();
    this.addAll(arrayList);

【讨论】:

【参考方案6】:
adapter.notifyDataSetChanged();

【讨论】:

请编辑更多信息。不建议使用纯代码和“试试这个”的答案,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。 在搜索上你要刷新适配器吗?【参考方案7】:

也许他们的问题是在数据库中进行搜索的那一刻。在他的 Fragment.java 的 Fragment Override 循环中弄清楚:尝试使用方法进行测试:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    View rootView = inflater.inflate(R.layout.fragment_x, container, false); //Your query and ListView code probably will be here
    Log.i("FragmentX", "Step OnCreateView");// Try with it
    return rootView; 

尝试类似地把Log.i ...“onStart”和“onResume”。

最后将“onCreate”中的代码剪掉,例如放在“onStart”中:

@Override
public void onStart()
    super.onStart();
    Log.i("FragmentX","Step OnStart");
    dbManager = new DBManager(getContext());
    Cursor cursor = dbManager.getAllNames();
    listView = (ListView)getView().findViewById(R.id.lvNames);
    adapter = new CustomCursorAdapter(getContext(),cursor,0);// your adapter
    adapter.notifyDataSetChanged();
    listView.setAdapter(adapter);

【讨论】:

【参考方案8】:

只需在您的自定义ArrayAdaper 中写入此代码:

private List<Cart_items> customListviewList ;

refreshEvents(carts);

public void refreshEvents(List<Cart_items> events)

    this.customListviewList.clear();
    this.customListviewList.addAll(events);
    notifyDataSetChanged();

【讨论】:

【参考方案9】:

在 Android 上刷新 Adapter/ListView 的最佳方式

不仅调用notifyDataSetChanged()会刷新ListView数据,之前必须调用setAdapter()才能正确加载信息:

  listView.setAdapter(adapter);
  adapter.notifyDataSetChanged();

【讨论】:

如果使用setAdaper,则不需要使用notifyDataSetChanged【参考方案10】:

如果没有任何效果,只需使用新的结果集或更新的结果集再次创建适配器实例。然后你就可以看到新的视图了。

XYZAdapter adbXzy = new XYZAdapter(context, 0, listData);
xyzListView.setAdapter(adbXzy);

adbXzy.notifyDataSetChanged();

【讨论】:

以上是关于在 Android 上刷新 Adapter/ListView 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

输入表单字段上的页面刷新触摸事件 - Android,Samsung

Android 下拉刷新上拉载入效果功能

案例:Android12上“显示刷新频率“点击无效

在 API 上添加新数据后如何在 android studio 上刷新 RecyclerView?

自个儿写Android的下拉刷新/上拉加载控件 (续)

[Android实例] Android 6.0RecyclerView SwipeRefreshLayout 下拉刷新 上拉加载