繁体   English   中英

当我从sqlite读取时,notifyDataSetChanged不起作用

[英]notifyDataSetChanged doesn't work when i am reading from sqlite

当我尝试从SQLite读取并使用adapter.NotifyDataSetChanged时。 我的recyclerView没有看到任何变化。 主要思想是在SQLite中搜索,其中名称包含来自textView的值。 然后重新填充我的适配器。

我创建一个实例

 private List<InventoryPreviewClass> mItems;
 private RecyclerView mRecyclerView;
 adpInventoryPreview adapter;

然后在onCreate()方法中

mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where CategoryID =" + CategoryID + ""); //Here i am reading from sqlite

mRecyclerView.HasFixedSize = true;
var layout = new GridLayoutManager(this, InventoryRowsPerLine, GridLayoutManager.Vertical, false);
mRecyclerView.SetLayoutManager(layout);
adapter = new adpInventoryPreview(mItems);
mRecyclerView.SetAdapter(adapter);

到现在为止,该代码仍然有效。 我recyclerView会填充的SQLite我的项目。

这是用户在TextView中键入内容时的方法

private void EtSearchAlwaysOn_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{      
   mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where  InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
   adapter.NotifyDataSetChanged();
}

当我输入内容时,recyclerView中没有任何变化。 为什么会这样呢?

我发现这可行的唯一方法是例如在适配器中重置我的物品:

mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where  InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
adapter = new adpInventoryPreview(mItems);
mRecyclerView.SetAdapter(adapter);

为什么会这样呢? 我认为第二种方法不正确。

发生这种情况是因为您要向mItems分配一个新对象

第一次创建mItems列表时,将其传递到适配器上,当您下次从SQLite DB获得响应时,由于将列表分配给对象,因此将创建该列表的新实例。

您需要做的是

  • 在适配器中创建一个接受您的项目的方法,例如adapter.updateItems(newItems)
  • 该方法应清除列表,例如items.clear() ,然后将您通过它传递的新项目与items.addAll(newItems)添加items.addAll(newItems)
  • 之后,您可以在适配器本身内调用notifyDataSetChanged() ,它将起作用。

在您的适配器中,它看起来像这样

public void updateItems(final List<InventoryPreviewClass> newItems) {
   items.clear();
   items.addAll(newItems);
   notifyDataSetChanged();
}

然后你可以这样称呼它

updatedList = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where CategoryID =" + CategoryID + "");

adapter.updateItems(updatedList);

我认为您错过了这是按值传递而不是按引用传递的典型情况的观点。

这是一个byRef问题。 您将内存指针1传递给适配器,并告诉它监视更改。

然后,加载列表并将内存指针指向点2。然后,告诉适配器在指针1处它监视的内存已更改。

您有两个选择。

  • 通过将新结果与旧结果进行比较来修改原始列表,并根据需要删除和添加
  • 或通过更改适配器内部的项目来告诉适配器它正在监视的新内存指针。 为swapItems(items)制作方法将起作用。 然后在适配器内部调用notifyDataSetChanged。

您必须在适配器中设置项目,像这样创建一个setter:

 private List<InventoryPreviewClass> mItems; . . . public void setItems(List<InventoryPreviewClass> items) { mItems=items; } 

然后像这样更新您的搜索方法

private void EtSearchAlwaysOn_TextChanged(object sender, 
 Android.Text.TextChangedEventArgs e)
 {      
 mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass 
 where  InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");
 adapter.setItems(mItems);
 adapter.NotifyDataSetChanged();
 }

设置适配器后通知适配器。

mItems = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where InventoryItemName like '%" + etSearchAlwaysOn.Text.ToUpper() + "%'");

adapter = new adpInventoryPreview(mItems);

mRecyclerView.SetAdapter(adapter);

adapter.notifyDataSetChanged();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM