android - SearchView 在 Android 中不起作用。为什么这样?
问题描述
我在我的应用程序中使用带有标题的 Recycleview,我正在尝试在我的应用程序中实现 searchview,但它不起作用。当我点击搜索视图并输入一些内容时,结果没有被过滤,我在我的日志猫中得到了这个。
2019-06-23 14:00:48.471 27193-27508/com.example.testapp W/Filter: An exception occured during performFiltering()!
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toLowerCase()' on a null object reference
at com.example.testapp.TitleAdapter$1.performFiltering(TitleAdapter.java:92)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:171)
at android.os.HandlerThread.run(HandlerThread.java:65)
我已经在这几个小时了,无法弄清楚我做错了什么。这是我的适配器。
public class TitleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private List <ItemObject> list;
private List <ItemObject> listFiltered;
private Context context;
public TitleAdapter(Context context, List <ItemObject> list) {
this.context = context;
this.list = list;
this.listFiltered = list;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout, parent, false);
return new HeaderViewHolder(layoutView);
} else if (viewType == TYPE_ITEM) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
return new ItemViewHolder(layoutView);
}
throw new RuntimeException("No match for " + viewType + ".");
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
ItemObject list = this.list.get(position);
if (holder instanceof HeaderViewHolder) {
((HeaderViewHolder) holder).headerTitle.setText(list.getHeaderTitle());
} else if (holder instanceof ItemViewHolder) {
((ItemViewHolder) holder).titleText.setText(list.getPageName());
}
}
public ItemObject getItem(int position) {
return list.get(position);
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public int getItemViewType(int position) {
if (isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
ItemObject mObject = list.get(position);
return mObject.isHeader();
}
@Override
public Filter getFilter() {
return new Filter() {
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint == null || constraint.length() == 0){
listFiltered = list;
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
List<ItemObject> lstFilter = new ArrayList<>();
for (ItemObject row : list) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getPageName().toLowerCase().contains(filterPattern)) {
lstFilter.add(row);
}
}
listFiltered = lstFilter;
}
FilterResults filterResults = new FilterResults();
filterResults.values = listFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
listFiltered = (List <ItemObject>) results.values;
// refresh the list with filtered data
notifyDataSetChanged();
}
};
}
public class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView headerTitle;
public HeaderViewHolder(View itemView) {
super(itemView);
headerTitle = itemView.findViewById(R.id.headerText);
}
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
TextView titleText;
public ItemViewHolder(View itemView) {
super(itemView);
titleText = itemView.findViewById(R.id.titleText);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = getAdapterPosition();
Intent intent = new Intent(context, ViewerActivity.class);
intent.putExtra("PageName",list.get(position).getPageName());
intent.putExtra("PageUrl",list.get(position).getPageUrl());
context.startActivity(intent);
}
});
}
}
}
顺便说一句,如果你想知道这是第 92 行
if (row.getPageName().toLowerCase().contains(filterPattern)) {
lstFilter.add(row);
}
解决方案
如您所知,有null
异常getPageName()
,所以检查一下
if(row.getPageName()!=null && !row.getPageName().isEmpty())
if (row.getPageName().toLowerCase().contains(filterPattern)) {
lstFilter.add(row);
}
我看到你有list
对象getItemCount()
,所以我假设主要的“列表”是list
所以你必须备份这个,在这一行做如下:
@Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
//listFiltered = (List <ItemObject>) results.values;
//back up `list` some where else for reloading the list without filter
list.clear();
list.addAll((List <ItemObject>) results.values);
// refresh the list with filtered data
notifyDataSetChanged();
}
备份原始数据并放入过滤器
推荐阅读
- javascript - 如何使用 NodeJS 将视频上传到 JW Dashboard?
- c# - Datagridview 选择的行单元格返回 null
- python - 组织 Python 库 + Flask 演示
- bash - 从标准输入读取变量时如何在 bash 中使用 GNU 并行?
- google-sheets - 根据入住和退房时间谷歌表格查找给定时间的总数
- paypal - 从旧的 PayPal 按钮过渡到 PayPal Javascript SDK 按钮
- javascript - 当托管在与应用程序本身不同的域上时,如何为 Web 组件获取 HTML 和 CSS 文件?
- python - 我不知道如何在函数中循环两次以修改列表
- list - 一个 2 元组整数列表有多少种方法可以组合成一个完整整数范围的有序元组?
- javascript - 如何在 Mapbox GL JS 中使用私有 Mapbox Tileset?