Android:如何在自定义RecyclerView Adapter中获取MatchActivity的正确引用以调用其Getter方法
解决RecyclerView Adapter中获取Activity正确引用的问题
兄弟,你现在的问题根源太明显了——你在onBindViewHolder()里直接new MatchActivity(),这根本不是当前正在运行的那个Activity实例啊!这个新创建的对象里的集合大概率是空的,或者和当前页面的真实数据完全不匹配,自然会触发IndexOutOfBoundsException。下面给你几个靠谱的解决办法:
方法一:直接传递Activity的引用(简单直接,但要注意内存泄漏)
1. 修改Adapter的构造函数
在MatchActivityPlayerAdapter里添加一个MatchActivity类型的成员变量,然后修改构造函数接收这个引用:
private final List<Player> playerList; private final Match match; private final MatchActivity matchActivity; // 持有Activity引用 // 更新构造函数 MatchActivityPlayerAdapter(List<Player> playerList, Match match, MatchActivity matchActivity) { this.playerList = playerList; this.match = match; this.matchActivity = matchActivity; }
2. 在MatchActivity中创建Adapter时传入自身引用
当你在MatchActivity里初始化Adapter的时候,把this传进去:
// 假设这是你初始化RecyclerView和Adapter的代码 MatchActivityPlayerAdapter adapter = new MatchActivityPlayerAdapter(playerList, yourMatchInstance, this); yourRecyclerView.setAdapter(adapter);
3. 修复onBindViewHolder中的代码
现在直接用传递过来的Activity引用,不要再new对象了,同时记得加个索引判断避免越界:
@Override public void onBindViewHolder(@NonNull MatchActivityPlayerRowViewHolder holder, int position) { final Player player = playerList.get(position); // 用传递过来的真实Activity引用 holder.nameTextView.setText(player.getPlayerName()); // 先判断索引是否合法,避免再次触发越界异常 if (position >= 0 && position < matchActivity.getRemainingPoints().size()) { holder.pointsTextView.setText(String.valueOf(matchActivity.getRemainingPoints().get(position))); holder.dart1.setText(String.valueOf(matchActivity.getDart1().get(position))); holder.dart2.setText(String.valueOf(matchActivity.getDart2().get(position))); holder.dart3.setText(String.valueOf(matchActivity.getDart3().get(position))); holder.dartsCombined.setText(String.valueOf(matchActivity.getDartsCombined().get(position))); } // holder.averageTextView.setText(matchActivity.getAverage().get(position)); }
方法二:传递数据而非Activity引用(更推荐,解耦+避免内存泄漏)
直接让Adapter持有Activity引用可能会导致内存泄漏(比如Activity销毁后Adapter还持有它的引用),更优雅的方式是把Adapter需要的数据直接传递过去,让Adapter只负责渲染数据,不依赖Activity:
1. 修改Adapter构造函数,直接接收所需数据
private final List<Player> playerList; private final Match match; private final List<Integer> remainingPoints; private final List<Integer> dart1; private final List<Integer> dart2; private final List<Integer> dart3; private final List<Integer> dartsCombined; // 更新构造函数,直接接收所有需要渲染的数据 MatchActivityPlayerAdapter(List<Player> playerList, Match match, List<Integer> remainingPoints, List<Integer> dart1, List<Integer> dart2, List<Integer> dart3, List<Integer> dartsCombined) { this.playerList = playerList; this.match = match; this.remainingPoints = remainingPoints; this.dart1 = dart1; this.dart2 = dart2; this.dart3 = dart3; this.dartsCombined = dartsCombined; }
2. 在MatchActivity中创建Adapter时传入数据
MatchActivityPlayerAdapter adapter = new MatchActivityPlayerAdapter( playerList, yourMatchInstance, getRemainingPoints(), getDart1(), getDart2(), getDart3(), getDartsCombined() ); yourRecyclerView.setAdapter(adapter);
3. 修改onBindViewHolder代码
现在直接用传入的数据列表即可:
@Override public void onBindViewHolder(@NonNull MatchActivityPlayerRowViewHolder holder, int position) { final Player player = playerList.get(position); holder.nameTextView.setText(player.getPlayerName()); if (position >= 0 && position < remainingPoints.size()) { holder.pointsTextView.setText(String.valueOf(remainingPoints.get(position))); holder.dart1.setText(String.valueOf(dart1.get(position))); holder.dart2.setText(String.valueOf(dart2.get(position))); holder.dart3.setText(String.valueOf(dart3.get(position))); holder.dartsCombined.setText(String.valueOf(dartsCombined.get(position))); } }
这样做的好处是Adapter和Activity完全解耦,既避免了内存泄漏风险,也让Adapter的复用性更强。
内容的提问来源于stack exchange,提问作者Blaupunkt
相关产品推荐
相关产品推荐

