android - Recyclerview 与 searchview 解除绑定问题
问题描述
我正在为我的 recyclerview 使用日期搜索过滤器,我的 performFiltering 日志给了我正确的记录集,recyclerview 显示的记录数是正确的,但数据不正确,我知道这是因为 recyclerview 回收视图但即使几个小时后,我找不到解绑数据的方法,以便显示准确的过滤结果。帮助!
package com.emlocks.timeaccess;
import android.app.DatePickerDialog;
import android.app.Notification;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.Filter;
import android.widget.Filterable;
import android.support.v7.widget.SearchView;
import android.widget.TextView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.emlocks.timeaccess.R.layout.list_item1;
public class NotificationList extends AppCompatActivity {
SharedPreferences prefs;
private Gson gson;
RecyclerView recyclerView;
List<Map<String, String>> notifList;
List<Map<String, String>> notifListFull;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
prefs = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);
gson = new Gson();
recyclerView = findViewById(R.id.notificationsRecycler);
prefs = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);
notifList = gson.fromJson(prefs.getString("notifs", ""), new TypeToken<List<Map<String, String>>>() {
}.getType());
notifListFull = new ArrayList<>(notifList);
recyclerView.setLayoutManager(new LinearLayoutManager(NotificationList.this));
recyclerView.setAdapter(new NotificationListAdapter());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.example_menu, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dilog = new DatePickerDialog(
NotificationList.this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
String monthText ;
String dayText;
month = month + 1;
if(month < 10){
monthText = "0" + month;
} else{
monthText = String.valueOf(month);
}
if(dayOfMonth<10){
dayText = "0" + dayOfMonth;
} else{
dayText = String.valueOf(dayOfMonth);
}
String date = dayText + "/" + monthText + "/" + year;
searchView.setQuery(date, true);
}
}, year, month, day
);
dilog.show();
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
new NotificationListAdapter().getFilter().filter(newText);
return false;
}
});
return true;
}
class NotificationListAdapter extends RecyclerView.Adapter<NotificationList.NotificationListAdapter.VH> implements Filterable {
@NonNull
@Override
public NotificationListAdapter.VH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
View listItem1 = layoutInflater.inflate(list_item1, viewGroup, false);
NotificationList.NotificationListAdapter.VH viewHolder = new NotificationList.NotificationListAdapter.VH(listItem1);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull NotificationList.NotificationListAdapter.VH vh, int i) {
Map<String, String> o = notifList.get(i);
Log.d("TAG", "perform " + notifList.get(i).get("title"));
vh.tv1.setText(o.get("title"));
vh.tv2.setText(o.get("body"));
}
@Override
public int getItemCount() {
return notifList.size();
}
@Override
public Filter getFilter() {
return notifFilter;
}
private Filter notifFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Map<String, String>> filteredList = new ArrayList<Map<String, String>>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(notifListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Map<String, String> item : notifList) {
if (item.get("title").toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
Log.d("TAG", "performFiltering: " + results.values);
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notifList.clear();
notifList.addAll((List<Map<String, String>>) results.values);
notifyDataSetChanged();
}
};
public class VH extends RecyclerView.ViewHolder {
TextView tv1, tv2;
public VH(View listItem1) {
super(listItem1);
this.tv1 = listItem1.findViewById(R.id.tvTitle);
this.tv2 = listItem1.findViewById(R.id.tvbody);
}
}
}
}
解决方案
您 NotificationListAdapter
每次都在制作新的,onQueryTextChange
而不是使用 RecyclerView 的适配器。
@Override
public boolean onQueryTextChange(String newText) {
recyclerView.getAdapter().getFilter().filter(newText);
return false;
}
推荐阅读
- python - 如何在 selenium python 的网站中搜索和选择第一个选项
- reactjs - AWS Amplify GraphQL 双 API 调用
- shopify - Dialogflow 和 shopify APi 在订单完成后通知用户
- rust - 错误:使用移动值:`path`。如何更正此代码?
- vuejs2 - 错误:找不到模块 'nanoid/non-secure'
- vba - 如何在允许您访问其方法的变量中保存对由 `querySelectorAll` 匹配的项目的引用?
- java - Junit5 LauncherDiscoveryRequestBuilder selectPackage 找不到测试
- r - 后续:为 data.frame 中的每个 id 值创建错误消息
- android - 将插件应用于 Gradle KTS 项目失败
- r - 识别直方图中的点