You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 17:30:05