RecyclerView with Adapter不将值存储在Android中



我有以下简单的回收视图布局:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SurvivorPicksheetActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

此回收器视图链接到列表项目的详细布局,例如:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_centerHorizontal="true"
app:srcCompat="@drawable/gamefield_background" />

<ImageView
android:id="@+id/away"
android:layout_width="160dp"
android:layout_height="150dp"
android:layout_gravity="top|left"/>

<ImageView
android:id="@+id/home"
android:layout_width="160dp"
android:layout_height="150dp"
android:layout_gravity="top|right"
android:scaleX="-1"/>
</androidx.cardview.widget.CardView>

</FrameLayout>
</LinearLayout>

在Adapterjava类中,我有一个用于两个ImageView项的setOnClickListener。

如果用户单击它们,则项目将被选中,而旧项目将被取消选中。

我遇到的问题是,假设项目列表有25个项目。如果我点击第三项,一切都如预期。

然后我滚动到列表的末尾,再向上滚动到顶部,即使我在滚动到列表末尾之前点击/选择了,选择也不再有效。

我可以重新点击顶部的项目,向下滚动再向上滚动,我的选择就消失了!?

有人知道为什么会发生这种事吗?更重要的是,我该如何解决!?

更新:

以下是我的适配器类:

public class GameAdapter extends 
RecyclerView.Adapter<GameAdapter.GameViewHolder> {
// variable that holds the selected team
private String selectedTeam = "";
@Override
public void onBindViewHolder(GameViewHolder holder, int position) {
final Games game = gameList.get(position);
holder.awayTeamImageView.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedTeam.equals(String.valueOf(game.getHomeId()))) {
// RESET PLAYER SELECTION
selectedTeam = "";
selectedGame = "";
} else {
// SET PLAYER SELECTION
selectedTeam = String.valueOf(game.getHomeId());
selectedGame = String.valueOf(game.getKey());
}
}
}
}
class GameViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

public GameViewHolder(@NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);

awayImageView = itemView.findViewById(R.id.away);
homeImageView = itemView.findViewById(R.id.home);

homeImageView.setOnClickListener(this);
awayImageView.setOnClickListener(this);
}
}

根据我上面的代码,我"认为"我正在设置和取消设置所选团队,这样当我滚动到最后并返回顶部时,所选团队应该保持不变,而不是被回收,不再显示?!

这是因为旧的Views正在被回收,回到初始状态。这是CCD_ 2的一种自然行为。

为了使每个项目CCD_;记住";在检查/选择状态下,您需要在模型类中创建一个字段来记录状态,如isCheckedisSelected

您可以使用自己的域ViewHolder和ViewModel进行recycleview。

Android开发人员文档在下面的链接中给出了如何创建动态RecycleView的基本理解。

https://developer.android.com/guide/topics/ui/layout/recyclerview

这是意料之中的事,因为每当您向上/向下滚动列表时,视图都会被回收并相应地丢失其值;此外,对于配置更改(如屏幕旋转(,所选视图将丢失。

要解决此问题,您应该使用ViewModel,以便即使在配置更改时也具有持久数据。

但是,作为救援者,假设适配器提供的游戏列表gameList在如上所述的持久存储器中;那么你可以:

  • 使用getter/setter在Games模型类中创建一个选择布尔值,该布尔值最初为false。

  • 当从RecyclerView中选择一行时,将布尔值设置为true,如gameList.get(selectedPosition).setIsSelected(true)

  • 然后是该位置的CCD_ 11。

最新更新