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); } } }
我确信自己的实现方式太过生硬,应该有更简洁的方案,目前仍在摸索中。
问题分析与修复方案
关键问题点
- 回调定义顺序错误:原代码中
ItemTouchHelper先于simpleCallback创建,会导致编译错误或空指针异常 - 重复修改数据:在
onSwiped中既调用了适配器的修改方法,又直接操作原始数组,导致数据一致性问题 - 变量定义缺失:
pitchAdapter1未在代码开头声明,存在语法错误 - 适配器冗余:
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);
核心优化点
- 调整滑动回调的定义顺序,解决语法错误
- 移除重复的数据操作,仅通过适配器方法修改数据,保证数据一致性
- 增加位置有效性判断,避免滑动时的异常崩溃
- 合并冗余适配器代码,减少重复逻辑,提升可维护性
内容的提问来源于stack exchange,提问作者phil360
相关产品推荐
相关产品推荐

