在 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
在 API 上添加新数据后如何在 android studio 上刷新 RecyclerView?
[Android实例] Android 6.0RecyclerView SwipeRefreshLayout 下拉刷新 上拉加载