为观察者创建接口:
interface ProgressListener {
void onProgressUpdate(String imagePath, int progress);
}
让视图持有者实现那个观察者并知道图像路径:
public class ViewHolder implements ProgressListener {
ImageView imgQueue;
ProgressBar pb;
TextView tv;
String imagePath; //set this in getView!
void onProgressUpdate(String imagePath, int progress) {
if (!this.imagePath.equals(imagePath)) {
//was not for this view
return;
}
pb.post(new Runnable() {
pb.setProgress(progress);
});
}
//your other code
}
适配器应保存特定图像路径/uri 的观察者地图,并具有由上传/下载任务调用的方法。还要添加方法来添加和删除观察者:
public class SelectedAdapter_Test extends BaseAdapter {
private Map<String, ProgressListener> mProgressListener = new HashMap<>();
//your other code
synchronized void addProgressObserver(String imagePath, ProgressListener listener) {
this.mListener.put(imagePath, listener);
}
synchronized void removeProgressObserver(String imagePath) {
this.mListener.remove(imagePath);
}
synchronized void updateProgress(String imagePath, int progress) {
ProgressListener l = this.mListener.get(imagePath);
if (l != null) {
l.onProgressUpdate(imagePath, progress);
}
}
//other code
}
在适配器的getView中将视图持有者注册为观察者:
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//other code
holder.imagePath = data.get(i).getSdcardPath();
this.addProgressObserver(holder.imagePath, holder);
return convertView;
}
现在的问题是,我们注册了观察者但没有取消注册。所以让适配器实现View.addOnAttachStateChangeListener:
public class SelectedAdapter_Test extends BaseAdapter implements View.addOnAttachStateChangeListener {
//other code
void onViewAttachedToWindow(View v) {
//We ignore this
}
void onViewDetachedFromWindow(View v) {
//View is not visible anymore unregister observer
ViewHolder holder = (ViewHolder) v.getTag();
this.removeProgressObserver(holder.imagePath);
}
//other code
}
在您返回视图时注册该观察者。
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//other code
convertView.addOnAttachStateChangeListener(this);
return convertView;
}
你终于可以告诉视图进度了:
@Override
public void transferred(long num) {
int progress = (int) ((num / (float) totalSize) * 100);
selectedAdapter.onProgressUpdate(listOfPhotos.get(i).getSdcardPath(), progress);
}
最后一个问题仍然存在,如果在上传过程中活动消失了怎么办?您需要检查活动是否仍然存在。也许在 onCreate 中将适配器中的标志设置为 true 并在 onDestroy 中设置为 false 就可以了。然后最后一个代码片段可以检查该标志并且不再通知适配器更改。
所以这基本上就是如何解决这个问题的想法。它有效吗?我不知道我是从头开始写的,没有经过任何测试。即使是这样,当进度为 0 或 100 时,您仍然必须管理状态。但我把它留给您。此外,您可能希望更改 RecyclerView 的 BaseAdapter,以便我们可以摆脱 View.addOnAttachStateChangeListener。