Android Adapter集成广告视图后FilterResults返回null报错问题
问题描述
我有一个实现了Filter方法用于获取搜索结果的Adapter,但FilterResults results始终返回null,该问题在我更新Adapter以集成广告视图后出现,我并未修改Filter相关代码,此前Filter功能运行完全正常。
我通过查看结果计数的日志,发现其始终返回0。
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable { Context context; ArrayList<Posts> postsArrayList; ArrayList<Posts> postsArrayListFull; public MyAdapter(Context context, ArrayList<Posts> postsArrayList) { this.context = context; this.postsArrayList = postsArrayList; postsArrayListFull = new ArrayList<>(postsArrayList); } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View viewer = inflater.inflate(R.layout.users_item, parent, false); RecyclerView.ViewHolder viewHolder = new MyViewHolder(viewer); switch (viewType){ case 1:{ View view = inflater.inflate(R.layout.users_item, parent, false); viewHolder = new MyViewHolder(view); break; } case 2:{ View view = inflater.inflate(R.layout.list_item_admob, parent, false); viewHolder = new ViewHolderAdMob(view); break; } } return viewHolder; } public static class ViewHolderAdMob extends RecyclerView.ViewHolder { public AdView mAdView; public ViewHolderAdMob(View view) { super(view); mAdView = view.findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); mAdView.loadAd(adRequest); mAdView.setAdListener(new AdListener() { @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { super.onAdFailedToLoad(loadAdError); Toast.makeText(getApplicationContext(), "Ad Failed", Toast.LENGTH_SHORT).show(); } }); } } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { switch (holder.getItemViewType()){ case 1:{ Posts post = postsArrayList.get(position); MyViewHolder viewHolder = (MyViewHolder) holder; viewHolder.txtTitle.setText(post.getTitle()); viewHolder.blood_chip.setText(post.getBloodtype()); viewHolder.city_chip.setText(post.getCity()); SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); Timestamp timestamp = post.getPosttime(); Date date = timestamp.toDate(); String posttime = formatter.format(date); viewHolder.timestamp.setText(posttime); if (!post.getImage().equals("null")) { Glide.with(viewHolder.image.getContext()).load(post.getImage()) .into(viewHolder.image); } viewHolder.root.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, post.getTitle() + " From New Adapter" , Toast.LENGTH_SHORT).show(); } }); break; } case 2:{ } } } @Override public int getItemCount() { return postsArrayList.size(); } @Override public Filter getFilter() { return Filters; } private Filter Filters = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList<Posts> filtredPosts= new ArrayList<>(); if (constraint == null || constraint.length() == 0){ filtredPosts.addAll(postsArrayListFull); }else { String searchString = constraint.toString().toLowerCase().trim(); for (Posts post : postsArrayListFull){ if (post.getTitle().toLowerCase().contains(searchString)){ filtredPosts.add(post); } } } FilterResults results = new FilterResults(); results.count = filtredPosts.size(); results.values = filtredPosts; return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results.count == 0) Log.e("COUNT " ,"" + results.count); postsArrayList.clear(); postsArrayList.addAll((ArrayList)results.values); notifyDataSetChanged(); } }; public static class MyViewHolder extends RecyclerView.ViewHolder{ public ConstraintLayout root; public TextView txtTitle, timestamp; public ImageView image; public ToggleButton fav; public Chip city_chip, blood_chip; public MyViewHolder(@NonNull View itemView) { super(itemView); root = itemView.findViewById(R.id.list_root); txtTitle = (TextView) itemView.findViewById(R.id.list_title); image = (ImageView)itemView.findViewById(R.id.list_image); fav = (ToggleButton)itemView.findViewById(R.id.favbutton); blood_chip = (Chip)itemView.findViewById(R.id.blood_chip); city_chip = (Chip)itemView.findViewById(R.id.city_chip); timestamp = (TextView) itemView.findViewById(R.id.list_timestamp); }}public int getItemViewType(int position) { return postsArrayList.get(position).getViewType(); }}
旧版MyAdapter.java(修改前可正常运行版本)
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements Filterable { Context context; ArrayList<Posts> postsArrayList; ArrayList<Posts> postsArrayListFull; public MyAdapter(Context context, ArrayList<Posts> postsArrayList) { this.context = context; this.postsArrayList = postsArrayList; postsArrayListFull = new ArrayList<>(postsArrayList); } @NonNull @Override public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.users_item, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) { Posts post = postsArrayList.get(position); holder.txtTitle.setText(post.getTitle()); holder.blood_chip.setText(post.getBloodtype()); holder.city_chip.setText(post.getCity()); SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); Timestamp timestamp = post.getPosttime(); Date date = timestamp.toDate(); String posttime = formatter.format(date); holder.timestamp.setText(posttime); if (!post.getImage().equals("null")) { Glide.with(holder.image.getContext()).load(post.getImage()) .into(holder.image); } holder.root.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, post.getTitle() + " From New Adapter" , Toast.LENGTH_SHORT).show(); } }); } @Override public int getItemCount() { return postsArrayList.size(); } @Override public Filter getFilter() { return Filters; } private Filter Filters = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList<Posts> filtredPosts= new ArrayList<>(); if (constraint == null || constraint.length() == 0){ filtredPosts.addAll(postsArrayListFull); }else { String searchString = constraint.toString().toLowerCase().trim(); for (Posts post : postsArrayListFull){ if (post.getTitle().toLowerCase().contains(searchString)){ filtredPosts.add(post); } } } FilterResults results = new FilterResults(); results.values = filtredPosts; return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { postsArrayList.clear(); postsArrayList.addAll((ArrayList)results.values); notifyDataSetChanged(); } }; public static class MyViewHolder extends RecyclerView.ViewHolder{ public ConstraintLayout root; public TextView txtTitle, timestamp; public ImageView image; public ToggleButton fav; public Chip city_chip, blood_chip; public MyViewHolder(@NonNull View itemView) { super(itemView); root = itemView.findViewById(R.id.list_root); txtTitle = (TextView) itemView.findViewById(R.id.list_title); image = (ImageView)itemView.findViewById(R.id.list_image); fav = (ToggleButton)itemView.findViewById(R.id.favbutton); blood_chip = (Chip)itemView.findViewById(R.id.blood_chip); city_chip = (Chip)itemView.findViewById(R.id.city_chip); timestamp = (TextView) itemView.findViewById(R.id.list_timestamp); }}}
补充说明
此前遗漏了搜索时的报错信息:
Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference
报错位置恰好是postsArrayList.addAll((ArrayList)results.values);这一行。
问题解决更新
最终定位到问题根因:待过滤的ArrayList中同时包含两种视图(普通内容视图、广告视图),原本的逻辑是每5条普通内容插入1条广告。需要先过滤出所有普通视图项存入单独的数组,再基于该数组执行搜索,即可正常返回结果,对应过滤代码如下:
ArrayList<Posts> postsArrayListwithoutads = new ArrayList<>(); for (int i = 0; i < postsArrayListFull.size(); i++){ Posts posts = postsArrayListFull.get(i); if (posts.getViewType() == 1){ postsArrayListwithoutads.add(posts); } }
内容的提问来源于stack exchange,提问作者AsperMed
相关产品推荐
相关产品推荐

