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

RecyclerView筛选后Item选中对应原始列表错误问题求助

RecyclerView筛选后Item选中异常问题修复

问题现象

使用自定义PayloadAdapter实现按服务器名称筛选功能后,选中筛选列表中的项时,实际选中的是原始未筛选列表对应位置的条目,而非当前筛选列表的项。例如点击筛选后的第一项,实际选中的是原始列表的第一项。

问题根源

你的Adapter存在两个核心错误:

  • 初始化时payloadListFiltered直接引用原始payloadList,导致两个列表指向同一内存地址,筛选逻辑完全失效
  • onBindViewHolder和getItemCount始终使用原始payloadList,而非筛选后的payloadListFiltered,导致筛选后UI展示的是筛选数据,但点击位置对应的还是原始列表的索引

修复方案

步骤1:分离列表引用

将筛选列表初始化为新的ArrayList,避免与原始列表共享内存空间

步骤2:统一数据源

在onBindViewHolder、getItemCount中使用payloadListFiltered作为数据源

步骤3:优化点击事件(可选)

直接传递选中的PayloadModel对象,而非位置索引,从根源避免位置匹配错误


修改后的PayloadAdapter代码

public class PayloadAdapter extends RecyclerView.Adapter<PayloadAdapter.ViewHolder> implements Filterable {

    private final List<PayloadModel> payloadList; // 原始全量数据
    public SimpleDraweeView selectedSImage;
    private OnItemClickListener listener;
    private final List<PayloadModel> payloadListFiltered; // 筛选后的数据

    public PayloadAdapter(List<PayloadModel> payloadList) {
        this.payloadList = payloadList;
        this.payloadListFiltered = new ArrayList<>(payloadList); // 初始化新列表,避免引用同一对象
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.spinner_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // 改用筛选后的列表获取数据
        PayloadModel payload = payloadListFiltered.get(position);
        holder.bind(payload);
    }

    @Override
    public int getItemCount() {
        // 返回筛选列表的长度
        return payloadListFiltered.size();
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String query = charSequence.toString().toLowerCase().trim();
                List<PayloadModel> filteredList = new ArrayList<>();
                if (query.isEmpty()) {
                    filteredList.addAll(payloadList);
                } else {
                    for (PayloadModel payload : payloadList) {
                        if (payload.getServerName().toLowerCase().contains(query)) {
                            filteredList.add(payload);
                        }
                    }
                }
                FilterResults results = new FilterResults();
                results.values = filteredList;
                return results;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                payloadListFiltered.clear();
                payloadListFiltered.addAll((List<PayloadModel>) filterResults.values);
                notifyDataSetChanged();
            }
        };
    }

    private void loadPayloadIcon() {
        neth("ze");
    }

    public void neth(String pogiko) {
        String flagUrl = "" + pogiko + ".webp";
        selectedSImage.setImageURI(flagUrl);
    }

    // 优化接口:直接传递选中的对象,而非位置
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }

    public interface OnItemClickListener {
        void onItemClick(PayloadModel payload);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView nameTextView, infoTextView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            nameTextView = itemView.findViewById(R.id.itemNamea);
            infoTextView = itemView.findViewById(R.id.sinf);
            selectedSImage = itemView.findViewById(R.id.itemImagea);
        }

        public void bind(PayloadModel payload) {
            nameTextView.setText(payload.getServerName());
            infoTextView.setText(payload.getPayloadInfo());
            loadPayloadIcon();
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (listener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            // 传递筛选列表中的对应对象
                            listener.onItemClick(payloadListFiltered.get(position));
                        }
                    }
                }
            });
        }
    }
}

修改后的PayloadActivity代码(对应接口调整)

public class PayloadActivity extends BaseActivity implements PayloadAdapter.OnItemClickListener {
    EditText editTextSearch;
    private wamp config;
    private Settings mConfig;
    private List<PayloadModel> payloadList;
    private PayloadAdapter adapter;
    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.server);

        final EditText editTextSearch = findViewById(R.id.editTextSearch);
        
        payloadList = new ArrayList<>();
        recyclerView = findViewById(R.id.recyclerView);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new PayloadAdapter(payloadList);
        recyclerView.setAdapter(adapter);
        adapter.setOnItemClickListener(this);

        loadPayloadData();

        editTextSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                adapter.getFilter().filter(charSequence);
            }

            @Override
            public void afterTextChanged(Editable editable) {}
        });
    }

    // 实现修改后的接口,直接获取选中的对象
    @Override
    public void onItemClick(PayloadModel payload) {
        // 直接使用选中的payload对象处理业务逻辑,无需通过位置查找
    }
}

关键修复点说明

  1. 列表引用分离:初始化payloadListFiltered时创建新的ArrayList,避免和原始列表共享内存空间,确保筛选操作不会修改原始数据
  2. 数据源统一:Adapter的所有数据操作(绑定、计数)都使用筛选后的列表,保证UI展示和数据索引一致
  3. 点击事件优化:直接传递选中的对象,彻底避免位置索引匹配错误的问题,代码逻辑更直观可靠

内容的提问来源于stack exchange,提问作者krypt central

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:26:00