いくつかの画像をAsyncTaskを介してSDcardにダウンロードし、完了時にリストビューに表示したいと思います。ダウンロードが開始されるとプログレスバーが表示され、ダウンロードが停止するとsdcardにダウンロードされた画像が表示されます。
遅延読み込みの投稿がたくさんあるのを見ましたが、画像を表示する前にプログレスバーを表示したいので、SDカードに保存したいと思います。
次のコードはほぼ問題なく機能しますが、問題は、画像をダウンロードしているときに、適切なアイテムに適切な画像が常に表示されないことです。私はアダプターで以下を使用しています:
public View getView(final int position, View convertView, ViewGroup parent) {
final PooHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.item_poo, null);
holder = new PooHolder();
holder.tvTime = (TextView)convertView.findViewById(R.id.tvTime);
holder.tvMessage = (TextView)convertView.findViewById(R.id.tvMessage);
holder.btnDislike = (ImageButton)convertView.findViewById(R.id.btnDislike);
holder.btnLike = (ImageButton)convertView.findViewById(R.id.btnLike);
holder.btnReport = (ImageButton)convertView.findViewById(R.id.btnReport);
holder.bar = (ProgressBar)convertView.findViewById(R.id.progressBar1);
holder.bar1 = (ProgressBar)convertView.findViewById(R.id.progressBar2);
holder.bar2 = (ProgressBar)convertView.findViewById(R.id.progressBar3);
holder.tvLikes = (TextView)convertView.findViewById(R.id.tvLikes);
holder.tvComments = (TextView)convertView.findViewById(R.id.tvComments);
holder.tvDislikes = (TextView)convertView.findViewById(R.id.tvDislike);
holder.imgPoo = (ImageView)convertView.findViewById(R.id.imgPoo);
convertView.setTag(holder);
}else{
holder = (PooHolder)convertView.getTag();
}
final Poo poo = list.get(position);
String vote = poo.getVote();
if(poo.getDrawablePath()!=null){
if(!poos.get(position).isDownloadComplete()){
Log.i(DEBUG, poo.getMessage());
holder.bar2.setVisibility(View.VISIBLE);
holder.imgPoo.setImageBitmap(BitmapFactory.decodeFile(poo.getDrawablePath()));
holder.imgPoo.setVisibility(View.INVISIBLE);
if(!poos.get(position).getDownloadState(Poo.DOWNLOAD_START)){
DownloadImageTask task = new DownloadImageTask(poo, holder.bar2, holder.imgPoo);
task.setOnDownloadListener(new OnDownloadListener(){
public void onDownloadStarted() {
poos.get(position).startDownload();
}
public void onDownloadFinished(final Bitmap bmp) {
poos.get(position).stopDownload();
}
});
task.execute(poo.getImagePath());
}
}else{
holder.bar2.setVisibility(View.INVISIBLE);
holder.imgPoo.setVisibility(View.VISIBLE);
holder.imgPoo.setImageBitmap(BitmapFactory.decodeFile(poo.getDrawablePath()));
}
}else{
holder.bar2.setVisibility(View.INVISIBLE);
holder.imgPoo.setVisibility(View.VISIBLE);
holder.imgPoo.setImageResource(R.drawable.icon);
}
....
DownloadImageTask.java:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private final String DEBUG = "DownloadImageTask";
private String url;
private String imagePath;
private OnDownloadListener listener;
private Bitmap bmp;
private ProgressBar bar;
private ImageView img;
private Poo poo;
public DownloadImageTask(Poo poo, ProgressBar bar, ImageView img) {
this.img = img;
this.bar = bar;
this.poo = poo;
}
public void onPreExecute(){
super.onPreExecute();
listener.onDownloadStarted();
bar.setVisibility(View.VISIBLE);
img.setImageBitmap(BitmapFactory.decodeFile(poo.getDrawablePath()));
img.setVisibility(View.INVISIBLE);
}
public void setOnDownloadListener(OnDownloadListener listener){
this.listener = listener;
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
this.imagePath = poo.getImagePath();
// params comes from the execute() call: params[0] is the url.
if(imagePath != null && !imagePath.isEmpty()){
String file = imagePath.substring(imagePath.lastIndexOf("/") + 1, imagePath.length());
return BoopoohooUtils.downloadImage(params[0], file);
}else{
return null;
}
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
Log.i(DEBUG, "bitmap " + bitmap);
bar.setVisibility(View.INVISIBLE);
img.startAnimation(BoopoohooUtils.fadeIn());
img.setVisibility(View.VISIBLE);
img.setImageBitmap(bitmap);
listener.onDownloadFinished(bitmap);
}
}