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

Android Studio中RecyclerView间CardView滑动迁移功能失效问题

问题:滑动RecyclerView的CardView实现Player对象在数组间迁移失败

我正在Android Studio中开发第一个Android项目,想要实现滑动RecyclerView里的CardView,让对应的Player对象在两个数组间迁移——滑动后该CardView会出现在另一个RecyclerView中。已经完成基础实现但功能无法正常运行,查过不少教程也试过AI工具,下面是RecyclerView相关的全部代码:

原项目代码

Activity中的RecyclerView配置代码

private PitchAdapter pitchAdapter2;
private BenchAdapter benchAdapter1;
private BenchAdapter benchAdapter2;

ArrayList<Player> playing = new ArrayList<>();
ArrayList<Player> playing2 = new ArrayList<>();
ArrayList<Player> benched1 = new ArrayList<>();
ArrayList<Player> benched2 = new ArrayList<>();

// Set up RecyclerViews In the OnCreate
RecyclerView field1RecyclerView = findViewById(R.id.field1);
RecyclerView field2RecyclerView = findViewById(R.id.field2);
RecyclerView bench1RecyclerView = findViewById(R.id.bench1);
RecyclerView bench2RecyclerView = findViewById(R.id.bench2);

LinearLayoutManager layoutManager1 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager layoutManager2 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager layoutManager3 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager layoutManager4 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

bench1RecyclerView.setLayoutManager(layoutManager1);
bench2RecyclerView.setLayoutManager(layoutManager2);
field1RecyclerView.setLayoutManager(layoutManager3);
field2RecyclerView.setLayoutManager(layoutManager4);


pitchAdapter1 = new PitchAdapter(this, playing);
pitchAdapter2 = new PitchAdapter(this, playing2);
benchAdapter1 = new BenchAdapter(this, benched1);
benchAdapter2 = new BenchAdapter(this, benched2);


field1RecyclerView.setAdapter(pitchAdapter1);
field2RecyclerView.setAdapter(pitchAdapter2);
bench1RecyclerView.setAdapter(benchAdapter1);
bench2RecyclerView.setAdapter(benchAdapter2);

ItemTouchHelper itemTouchHelper1 = new ItemTouchHelper(simpleCallback);
android.util.Log.d("STRING",  "CHECKINGATTACH");
itemTouchHelper1.attachToRecyclerView(bench1RecyclerView);


ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        if(direction == ItemTouchHelper.LEFT){
            android.util.Log.d("TAG", "CHECK");
            int position = viewHolder.getAdapterPosition();
            Player player = benchAdapter1.getPlayerAtPosition(position);

            // Update bench adapter and field adapter
            benchAdapter1.removePlayerAtPosition(position);
            pitchAdapter1.addPlayer(player);

            // Update underlying data structures
            benched1.remove(player);
            playing.add(player);

        }
    }
};

BenchAdapter代码

package com.example.teamcreatorv2.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.teamcreatorv2.Items.Player;
import com.example.teamcreatorv2.R;

import java.util.ArrayList;

public class BenchAdapter extends RecyclerView.Adapter<BenchAdapter.benchViewHolder> {


    Context context;
    ArrayList<Player> players;

    public BenchAdapter(Context context, ArrayList<Player> players) {
        this.context = context;
        this.players = players;
    }

    public Player getPlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            return players.get(position);
        }
        return null;
    }

    // Method to remove a player at a specific position
    public void removePlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            players.remove(position);
            notifyItemRemoved(position);
        }
    }

    @NonNull
    @Override
    public BenchAdapter.benchViewHolder onCreateViewHolder (@NonNull ViewGroup parent, int viewType){
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.pitch_cards, parent, false);
        return new BenchAdapter.benchViewHolder(view);
    }

    @Override
    public void onBindViewHolder (@NonNull BenchAdapter.benchViewHolder holder,int position){
        holder.Name.setText(players.get(position).getPlayerName());
        holder.Num.setText(players.get(position).getPlayerNumber());
    }

    @Override
    public int getItemCount () {
        return players.size();
    }

    public static class benchViewHolder extends RecyclerView.ViewHolder {
        TextView Num;
        TextView Name;

        public benchViewHolder(@NonNull View itemView) {
            super(itemView);
            Num = itemView.findViewById(R.id.Num);
            Name = itemView.findViewById(R.id.Name);
        }
    }
}

PitchAdapter代码

package com.example.teamcreatorv2.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.teamcreatorv2.Items.Player;
import com.example.teamcreatorv2.R;

import java.util.ArrayList;

public class PitchAdapter extends RecyclerView.Adapter<PitchAdapter.pitchViewHolder> {

    Context context;
    ArrayList<Player> players;

    public PitchAdapter(Context context, ArrayList<Player> players){
        this.context = context;
        this.players = players;
    }

    // Method to get a player at a specific position
    public Player getPlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            return players.get(position);
        }
        return null;
    }

    // Method to remove a player at a specific position
    public void removePlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            players.remove(position);
            notifyItemRemoved(position);
        }
    }

    public void addPlayer(Player player) {
        players.add(player);
        notifyItemInserted(players.size() - 1);
    }

    @NonNull
    @Override
    public PitchAdapter.pitchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.pitch_cards, parent, false);
        return new PitchAdapter.pitchViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PitchAdapter.pitchViewHolder holder, int position) {
        Player player = players.get(position);
        holder.Name.setText(players.get(position).getPlayerName());
        holder.Num.setText(players.get(position).getPlayerNumber());
    }

    @Override
    public int getItemCount() {
        return players.size();
    }

    public static class pitchViewHolder extends RecyclerView.ViewHolder{
        TextView Num;
        TextView Name;
        public pitchViewHolder(@NonNull View itemView){
            super(itemView);
            Num = itemView.findViewById(R.id.Num);
            Name = itemView.findViewById(R.id.Name);
        }
    }
}

我确信自己的实现方式太过生硬,应该有更简洁的方案,目前仍在摸索中。


问题分析与修复方案

关键问题点

  1. 回调定义顺序错误:原代码中ItemTouchHelper先于simpleCallback创建,会导致编译错误或空指针异常
  2. 重复修改数据:在onSwiped中既调用了适配器的修改方法,又直接操作原始数组,导致数据一致性问题
  3. 变量定义缺失:pitchAdapter1未在代码开头声明,存在语法错误
  4. 适配器冗余:BenchAdapter和PitchAdapter功能完全一致,重复代码过多

修复后的代码

修正后的Activity代码

// 补全缺失的变量定义
private PitchAdapter pitchAdapter1;
private PitchAdapter pitchAdapter2;
private BenchAdapter benchAdapter1;
private BenchAdapter benchAdapter2;

ArrayList<Player> playing = new ArrayList<>();
ArrayList<Player> playing2 = new ArrayList<>();
ArrayList<Player> benched1 = new ArrayList<>();
ArrayList<Player> benched2 = new ArrayList<>();

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

    // 初始化RecyclerView
    RecyclerView field1RecyclerView = findViewById(R.id.field1);
    RecyclerView field2RecyclerView = findViewById(R.id.field2);
    RecyclerView bench1RecyclerView = findViewById(R.id.bench1);
    RecyclerView bench2RecyclerView = findViewById(R.id.bench2);

    // 设置布局管理器
    LinearLayoutManager layoutManager1 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    LinearLayoutManager layoutManager2 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    LinearLayoutManager layoutManager3 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    LinearLayoutManager layoutManager4 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

    bench1RecyclerView.setLayoutManager(layoutManager1);
    bench2RecyclerView.setLayoutManager(layoutManager2);
    field1RecyclerView.setLayoutManager(layoutManager3);
    field2RecyclerView.setLayoutManager(layoutManager4);

    // 初始化适配器
    pitchAdapter1 = new PitchAdapter(this, playing);
    pitchAdapter2 = new PitchAdapter(this, playing2);
    benchAdapter1 = new BenchAdapter(this, benched1);
    benchAdapter2 = new BenchAdapter(this, benched2);

    // 绑定适配器
    field1RecyclerView.setAdapter(pitchAdapter1);
    field2RecyclerView.setAdapter(pitchAdapter2);
    bench1RecyclerView.setAdapter(benchAdapter1);
    bench2RecyclerView.setAdapter(benchAdapter2);

    // 先定义滑动回调,再创建ItemTouchHelper
    ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
            if (direction == ItemTouchHelper.LEFT) {
                int position = viewHolder.getAdapterPosition();
                // 防止无效位置引发错误
                if (position == RecyclerView.NO_POSITION) return;

                Player player = benchAdapter1.getPlayerAtPosition(position);
                if (player == null) return;

                // 仅通过适配器方法修改数据,避免重复操作
                benchAdapter1.removePlayerAtPosition(position);
                pitchAdapter1.addPlayer(player);
            }
        }
    };

    // 绑定滑动回调到RecyclerView
    ItemTouchHelper itemTouchHelper1 = new ItemTouchHelper(simpleCallback);
    itemTouchHelper1.attachToRecyclerView(bench1RecyclerView);
}

优化后的通用适配器(替代BenchAdapter和PitchAdapter)

package com.example.teamcreatorv2.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.teamcreatorv2.Items.Player;
import com.example.teamcreatorv2.R;

import java.util.ArrayList;

public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.PlayerViewHolder> {

    private Context context;
    private ArrayList<Player> players;

    public PlayerAdapter(Context context, ArrayList<Player> players) {
        this.context = context;
        this.players = players;
    }

    public Player getPlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            return players.get(position);
        }
        return null;
    }

    public void removePlayerAtPosition(int position) {
        if (position >= 0 && position < players.size()) {
            players.remove(position);
            notifyItemRemoved(position);
        }
    }

    public void addPlayer(Player player) {
        players.add(player);
        notifyItemInserted(players.size() - 1);
    }

    @NonNull
    @Override
    public PlayerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.pitch_cards, parent, false);
        return new PlayerViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PlayerViewHolder holder, int position) {
        Player player = players.get(position);
        holder.Name.setText(player.getPlayerName());
        holder.Num.setText(player.getPlayerNumber());
    }

    @Override
    public int getItemCount() {
        return players.size();
    }

    public static class PlayerViewHolder extends RecyclerView.ViewHolder {
        TextView Num;
        TextView Name;

        public PlayerViewHolder(@NonNull View itemView) {
            super(itemView);
            Num = itemView.findViewById(R.id.Num);
            Name = itemView.findViewById(R.id.Name);
        }
    }
}

适配器初始化替换(Activity中)

// 使用通用适配器替代原有的两个适配器
pitchAdapter1 = new PlayerAdapter(this, playing);
pitchAdapter2 = new PlayerAdapter(this, playing2);
benchAdapter1 = new PlayerAdapter(this, benched1);
benchAdapter2 = new PlayerAdapter(this, benched2);

核心优化点

  1. 调整滑动回调的定义顺序,解决语法错误
  2. 移除重复的数据操作,仅通过适配器方法修改数据,保证数据一致性
  3. 增加位置有效性判断,避免滑动时的异常崩溃
  4. 合并冗余适配器代码,减少重复逻辑,提升可维护性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:10:55