recyclerview 定期 ui 子更新
recyclerview periodic ui child updates
我有一个项目的 recyclerView,(除其他外)包含从 WS 检索的游戏持续时间的时间戳。为了显示比赛的持续时间,我必须获取当前时间戳,做垫子并将其转换为可读格式(例如:5 分钟 5 秒)。只有部分视图需要更新。
每个子视图需要每 xxx 秒更新一次。
我的第一个方法是创建一个绑定到需要更新的视图的对象列表。在我的片段上,我会声明一个 Handler 并为列表中的每个对象调用 notifyItemChanged(position)。每次处理程序调用 notifyItemChanged 时,整个视图都会重新呈现,并且有一个小的闪烁效果。我不希望它发生,所以我的第二种方法是只更改需要更新的每个 childView 的 TextView。这是代码:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (needsUpdate) {
holder.startRepeatingTask();
} else {
holder.stopRepeatingTask();
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final int mHandlerInterval = 6000;
private Handler mHandler;
private Runnable mStatusChecker;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.inject(this, itemView);
mHandler = new Handler();
mStatusChecker = new Runnable() {
@Override
public void run() {
String gameStatusToPrint = current.getGameStatusToPrint();
gameStatus.setText(gameStatusToPrint);
mHandler.postDelayed(mStatusChecker, mHandlerInterval);
}
};
}
public void startRepeatingTask() {
mStatusChecker.run();
}
public void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
}
我不确定这是否是最佳方法,需要对此提出建议。
因为ViewHolder要被RecyclerView回收。您需要确保保持 "current game" 和列表中显示的项目之间的稳定性。尽管如此,我认为您的解决方案很好。
解决方法如下:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.game = mGameList.get(position);
if (needsUpdate) {
holder.startRepeatingTask();
} else {
holder.stopRepeatingTask();
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final int mHandlerInterval = 6000;
private Handler mHandler;
private Runnable mStatusChecker;
public Game game;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.inject(this, itemView);
mHandler = new Handler();
mStatusChecker = new Runnable() {
@Override
public void run() {
String gameStatusToPrint = game.getGameStatusToPrint();
gameStatus.setText(gameStatusToPrint);
mHandler.postDelayed(mStatusChecker, mHandlerInterval);
}
};
}
public void startRepeatingTask() {
mStatusChecker.run();
}
我有一个项目的 recyclerView,(除其他外)包含从 WS 检索的游戏持续时间的时间戳。为了显示比赛的持续时间,我必须获取当前时间戳,做垫子并将其转换为可读格式(例如:5 分钟 5 秒)。只有部分视图需要更新。
每个子视图需要每 xxx 秒更新一次。
我的第一个方法是创建一个绑定到需要更新的视图的对象列表。在我的片段上,我会声明一个 Handler 并为列表中的每个对象调用 notifyItemChanged(position)。每次处理程序调用 notifyItemChanged 时,整个视图都会重新呈现,并且有一个小的闪烁效果。我不希望它发生,所以我的第二种方法是只更改需要更新的每个 childView 的 TextView。这是代码:
@Override public void onBindViewHolder(MyViewHolder holder, int position) { if (needsUpdate) { holder.startRepeatingTask(); } else { holder.stopRepeatingTask(); } } class MyViewHolder extends RecyclerView.ViewHolder { private final int mHandlerInterval = 6000; private Handler mHandler; private Runnable mStatusChecker; public MyViewHolder(View itemView) { super(itemView); ButterKnife.inject(this, itemView); mHandler = new Handler(); mStatusChecker = new Runnable() { @Override public void run() { String gameStatusToPrint = current.getGameStatusToPrint(); gameStatus.setText(gameStatusToPrint); mHandler.postDelayed(mStatusChecker, mHandlerInterval); } }; } public void startRepeatingTask() { mStatusChecker.run(); } public void stopRepeatingTask() { mHandler.removeCallbacks(mStatusChecker); } }
我不确定这是否是最佳方法,需要对此提出建议。
因为ViewHolder要被RecyclerView回收。您需要确保保持 "current game" 和列表中显示的项目之间的稳定性。尽管如此,我认为您的解决方案很好。
解决方法如下:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.game = mGameList.get(position);
if (needsUpdate) {
holder.startRepeatingTask();
} else {
holder.stopRepeatingTask();
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final int mHandlerInterval = 6000;
private Handler mHandler;
private Runnable mStatusChecker;
public Game game;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.inject(this, itemView);
mHandler = new Handler();
mStatusChecker = new Runnable() {
@Override
public void run() {
String gameStatusToPrint = game.getGameStatusToPrint();
gameStatus.setText(gameStatusToPrint);
mHandler.postDelayed(mStatusChecker, mHandlerInterval);
}
};
}
public void startRepeatingTask() {
mStatusChecker.run();
}