簡體   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