gpt4 book ai didi

android - RecyclerView overdraw 项目

转载 作者:行者123 更新时间:2023-11-29 01:06:06 25 4
gpt4 key购买 nike

我在所有 RecyclerView 上都遇到了一个很奇怪的问题在我的申请中。这不是我第一次使用 RecyclerView但这是第一次发生。我认为最好的解释方式是用照片:

列表不断更新,因此经常调用通知方法。代码有点太复杂,无法发布,但我确信一切都是从 UI 线程调用的。

此处要求的是代码和布局。

代码:

public class PlayersAdapter extends RecyclerView.Adapter<PlayersAdapter.ViewHolder> {
private final List<GameInfo.Player> players;
private final LayoutInflater inflater;

public PlayersAdapter(Context context, List<GameInfo.Player> players) {
this.inflater = LayoutInflater.from(context);
this.players = players;
setHasStableIds(true);
}

@Override
public long getItemId(int position) {
return players.get(position).name.hashCode();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(parent);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
GameInfo.Player player = players.get(position);
holder.name.setText(player.name);
holder.update(player);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position);
} else {
holder.update((GameInfo.Player) payloads.get(0));
}
}

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

public void notifyItemChanged(GameInfo.Player player) {
int pos = players.indexOf(player);
if (pos != -1) {
players.set(pos, player);
notifyItemChanged(pos, player);
}
}

public void notifyDataSetChanged(List<GameInfo.Player> players) {
this.players.clear();
this.players.addAll(players);
notifyDataSetChanged();
}

public class ViewHolder extends RecyclerView.ViewHolder {
final TextView name;
final SuperTextView score;
final ImageView status;

ViewHolder(ViewGroup parent) {
super(inflater.inflate(R.layout.player_item, parent, false));
setIsRecyclable(false);

name = itemView.findViewById(R.id.playerItem_name);
score = itemView.findViewById(R.id.playerItem_score);
status = itemView.findViewById(R.id.playerItem_status);
}

void update(GameInfo.Player player) {
score.setHtml(R.string.score, player.score);

switch (player.status) {
case HOST:
status.setImageResource(R.drawable.ic_person_black_48dp);
break;
case IDLE:
status.setImageResource(R.drawable.ic_access_time_black_48dp);
break;
case JUDGING:
case JUDGE:
status.setImageResource(R.drawable.ic_gavel_black_48dp);
break;
case PLAYING:
status.setImageResource(R.drawable.ic_hourglass_empty_black_48dp);
break;
case WINNER:
status.setImageResource(R.drawable.ic_star_black_48dp);
break;
case SPECTATOR:
status.setImageResource(R.drawable.ic_remove_red_eye_black_48dp);
break;
}
}
}
}

GameInfo.Player类:

public static class Player {
public final String name;
public final int score;
public final PlayerStatus status;

public Player(JSONObject obj) throws JSONException {
name = obj.getString("N");
score = obj.getInt("sc");
status = PlayerStatus.parse(obj.getString("st"));
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Player player = (Player) o;
return name.equals(player.name);
}
}

自定义项目布局(R.layout.player_item):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="4dp">

<ImageView
android:id="@+id/playerItem_status"
android:layout_width="32dp"
android:layout_height="32dp"
android:alpha="0.54"
android:padding="4dp"
android:scaleType="fitCenter" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="8dp">

<TextView
android:id="@+id/playerItem_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textColor="@android:color/primary_text_light"
android:textSize="14sp" />

<com.gianlu.commonutils.SuperTextView
android:id="@+id/playerItem_score"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

编辑:删除 onBindViewHolder(ViewHolder holder, int position, List<Object> payloads)方法仅在我使用 notifyItemChanged(pos, player) 时才解决问题,问题仍然存在 notifyItemChanged(pos) .很高兴知道为什么会这样。

最佳答案

我已经通过删除 onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) 解决了这个问题方法,使用 notifyItemChanged(pos)而不是 notifyItemChanged(pos, player)并设置 ViewHolder可回收 setIsRecyclable(true) .感谢@RahulKumar 的建议。

关于android - RecyclerView overdraw 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47053131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com