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

Android Java实现RecyclerView多选item点击切换LinearLayout背景

RecyclerView多选切换Item背景实现方法

核心要解决两个问题:一是独立存储每个item的选中状态,避免RecyclerView复用导致状态错乱;二是点击时更新状态、局部刷新item,保证交互流畅。具体修改步骤如下:

前置准备

先准备好选中状态的LinearLayout背景资源,比如默认背景是你现有的@drawable/gradient,选中背景自行命名为gradient_selected放到drawable目录下即可。

代码修改

XML布局不需要改动,直接修改Adapter代码,新增状态存储、点击逻辑、状态绑定即可:

// 顶部补充需要导入的工具类
import android.util.SparseBooleanArray;
import androidx.core.content.ContextCompat;
import android.graphics.drawable.Drawable;
import java.util.ArrayList;
import java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    String[] adkr;
    String[] repeat;
    Animation anim;
    Context co;
    // 存储每个item的选中状态,key=item位置,value=是否选中,比HashMap内存占用更低
    private final SparseBooleanArray selectedState = new SparseBooleanArray();
    // 预加载两个状态的背景,避免每次绑定都重复读取资源
    private final Drawable defaultBackground;
    private final Drawable selectedBackground;

    public MyAdapter(Context context, String[] all_adkars, String[] all_repeat) {
        co = context;
        adkr = all_adkars;
        repeat = all_repeat;
        // 初始化背景
        defaultBackground = ContextCompat.getDrawable(co, R.drawable.gradient);
        selectedBackground = ContextCompat.getDrawable(co, R.drawable.gradient_selected);
        // 初始化所有item默认未选中
        for (int i = 0; i < adkr.length; i++) {
            selectedState.put(i, false);
        }
    }


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(co);
        View view = layoutInflater.inflate(R.layout.custom_list, parent, false);
        return new MyViewHolder(view);
    }


    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.textView.setText(adkr[position]);
        holder.repeat_Tv.setText(repeat[position]);
        // 核心:每次绑定item时,根据存储的状态设置对应背景,解决复用错乱问题
        boolean isItemSelected = selectedState.get(position, false);
        holder.layout.setBackground(isItemSelected ? selectedBackground : defaultBackground);
        
        // 绑定点击事件,如果只想点击LinearLayout触发,把itemView换成holder.layout即可
        holder.itemView.setOnClickListener(v -> {
            // 翻转当前item的选中状态
            boolean newSelectState = !selectedState.get(position, false);
            selectedState.put(position, newSelectState);
            // 只刷新当前点击的item,比全量刷新性能好太多
            notifyItemChanged(position);
        });

        setAnimation(holder.itemView,position);
    }

    @Override
    public int getItemCount() {
        return adkr.length;
    }

    // 可选方法:需要获取所有选中item位置的时候直接调用
    public List<Integer> getSelectedItemPositions() {
        List<Integer> selectedList = new ArrayList<>();
        for (int i = 0; i < selectedState.size(); i++) {
            if (selectedState.valueAt(i)) {
                selectedList.add(selectedState.keyAt(i));
            }
        }
        return selectedList;
    }


    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView textView, repeat_Tv;
        LinearLayout layout;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
            repeat_Tv = itemView.findViewById(R.id.repeat);
            layout = itemView.findViewById(R.id.ll_bg);
        }
    }

    private void setAnimation(View viewToAnimate, int position) {
        anim = AnimationUtils.loadAnimation(co, R.anim.list_anim);
        viewToAnimate.startAnimation(anim);
    }
}

注意事项

  • 绝对不要只在点击监听里直接修改layout的背景,不存状态的话,RecyclerView滑动复用ViewHolder的时候,选中状态会随机串到其他item上,必须在onBindViewHolder里根据存储的状态统一设置UI。
  • 用notifyItemChanged(position)做局部刷新,不要每次点击都调用notifyDataSetChanged(),否则列表会卡顿,还会丢失item动画。
  • 如果需要默认选中部分item,只要在Adapter初始化的时候往selectedState里对应位置put true即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:12:15