[英]Filtering CardView with RecyclerView, not updating cards, always showing first cards
我正在使用Cardview來填充我的recyclerview。
我正在使用EditText字段進行過濾,這在調試時可以正常運行。
問題是,當我調用adapter.notifyDataSetChanged();
頭牌停留。 (取決於通過過濾器的卡數量)
我正在過濾的4個字符串是
Antwerpen
Deinze
Gent
Edegem
在圖像上,您可以看到帶有"ge"
卡片有2張,但是只有2張頂部的卡片..不是正確的字符串。
我擺弄了container.removeAllViewsInLayout();
在我的片段中,但是我不確定在哪里實現。 我在layoutInflater
之前在OnCreateViewHolder
進行了此操作,但隨后過濾器起作用了,但卡顯示得不好。
更新
我已經執行了Jeffalee給出的答案,謝謝您的回復!
但是,不走運,仍然遇到同樣的問題,我將在下面發布我的代碼。
適配器:
public class GemeenteAdapter extends RecyclerView.Adapter<GemeenteAdapter.GemeenteViewHolder> {
private List<Gemeente> gemeentes;
private List<Gemeente> filteredList;
public GemeenteAdapter(List<Gemeente> gemeentes, List<Gemeente> original) {
this.gemeentes = gemeentes;
filteredList = new ArrayList<>();
}
@Override
public int getItemCount() {
if (isFilterActive) {
return filteredList.size();
} else {
return gemeentes.size();
}
}
@Override
public void onBindViewHolder(GemeenteAdapter.GemeenteViewHolder holder, int i) {
Gemeente gemeente;
if (isFilterActive) {
gemeente = filteredList.get(i);
} else {
gemeente = gemeentes.get(i);
}
GemeenteViewHolder.vNaam.setText(gemeente.naam);
}
@Override
public GemeenteViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_cardview_small, viewGroup, false);
return new GemeenteViewHolder(v);
}
public static class GemeenteViewHolder extends RecyclerView.ViewHolder {
protected static TextView vNaam;
public GemeenteViewHolder(View v) {
super(v);
vNaam = (TextView) v.findViewById(R.id.txtNaam);
}
}
/**
* FILTER TEST 2
*/
boolean isFilterActive = false;
public void setFilter(String searchCriteria) {
setFilteredItems(searchCriteria);
isFilterActive = true;
notifyDataSetChanged();
}
public void clearFilter() {
isFilterActive = false;
notifyDataSetChanged();
}
private void setFilteredItems(String searchCriteria) {
System.out.println(searchCriteria);
for (Gemeente item : gemeentes) {
if (item.getNaam().toLowerCase().trim().contains(searchCriteria.toLowerCase())) {
System.out.println(item.getNaam());
filteredList.add(item);
}
}
}
分段:
public class FragmentSearch extends Fragment {
//Methode om de fragment te initializeren
public static FragmentSearch newInstance() {
FragmentSearch fragment = new FragmentSearch();
return fragment;
}
public FragmentSearch() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recycler_gemeente, container, false);
Context context = getActivity();
RecyclerView rv = (RecyclerView) view.findViewById(R.id.cardList);
rv.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(context);
llm.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(llm);
Gemeente gemeente = new Gemeente();
final GemeenteAdapter adapter = new GemeenteAdapter(gemeente.init(),gemeente.init());
rv.setAdapter(adapter);
/**
* Set filter when text is changed in EditText
*/
final EditText yourEditText = (EditText) view.findViewById(R.id.edittext);
yourEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
adapter.setFilter(yourEditText.getText().toString());
}
});
return view;
}
我希望這能給你們更多的信息。
發生的情況是搜索標准“ ge”有兩個結果,即Gent和Edegem。 您將Adapter
的數量設置為正確的數量(在這種情況下為2)。 但是,在您的onBindViewHolder()
方法中,您忘記了過濾后的項目List
的位置。 下面是我通常要做的過濾RecyclerView
的操作。
第1步:為RecyclerView
創建一個自定義Adapter
(我假設您已經這樣做了)
第2步:創建第二個項目List
(我假設您使用的是String
的ArrayList
),其中將填充與搜索條件匹配的項目(在本示例中為'ge')和一個boolean
,該boolean
將跟蹤Adapter
應使用過濾List
或非過濾List
List<String> items = new ArrayList<>();
List<String> filteredItems = new ArrayList<>();
boolean isFilterActive = false;
步驟3:在您的自定義適配器中創建一個setFilter(String searchCriteria)
和setFilter(String searchCriteria)
clearFilter()
方法,如下所示:
public void setFilter(String searchCriteria) {
setFilteredItems(searchCriteria);
isFilterActive = true;
notifyDataSetChanged();
}
public void clearFilter() {
isFilterActive = false;
notifyDataSetChanged();
}
private void setFilteredItems(String searchCriteria) {
for(String item: items) {
if(item.toLowerCase().contains(searchCriteria.toLowerCase())) {
filteredItems.add(item);
}
}
}
步驟4:返回正確的項目計數和每個位置的正確項目。 要為過濾的項目返回正確的金額,只需使用以下命令:
@Override
public int getItemCount() {
if(isFilterActive) {
return filteredItems.size();
} else {
return items.size();
}
}
為了使正確的項目顯示在RecyclerView中,請使用以下命令:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String item;
if (isFilterActive) {
item = filteredItems.get(position);
} else {
item = items.get(position);
}
//TODO set the value of 'item' to your TextView
}
步驟5:調用過濾器方法。 必要時,您可以簡單地從RecyclerView獲取適配器,然后調用set / clear過濾器方法(將其強制轉換為自定義Adapter
類之后),如下所示:
MyCustomAdapter adapter = (MyCustomAdapter) myRecyclerView.getAdapter();
adapter.setFilter("ge");
要么
adapter.clearFilter();
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.