#java #android #listview #android_asynctask
Есть ListView в которое по нажатию кнопки должен добавлять новый элемент с ProgressTab
и невидимое ImageView.
ImageView сразу начинает конвертироваться в нужное нам изображение через AsyncTask
и прогресс конвертирования отображается в ProgressTab. Когда конвертирование закончилось,
ProgressTab удаляется, а вImageView сеттится картинка и она становится видимой.
Но после 3 или 4 повторения операции это перестает работать и в ImageView сразу сеттится
рандомная из картинок, которые были обработаны до этого. (как я понял, такое происходит,
когда элементы из listView перестают быть видными на экране). Как это можно решить?
И вообще правилен ли у меня подход?
Код адаптера:
public class ListAdapter extends BaseAdapter {
Context context;
List dataList;
public ListAdapter(Context context, List dataList) {
this.context = context;
this.dataList = dataList;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
static class ViewHolder{
ImageView image;
ProgressBar progressBar;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View v = convertView;
ViewHolder holder;
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inf.inflate(R.layout.item_progress, null);
holder = new ViewHolder();
holder.image = (ImageView) v.findViewById(R.id.itemProgress_previewImage);
holder.progressBar = (ProgressBar) v.findViewById(R.id.itemProgress_progressBar);
v.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (holder.progressBar.getProgress() == 0 && holder.progressBar.getVisibility()
== View.VISIBLE) {
ConvertImageTask convertImageTask = new ConvertImageTask(holder.progressBar,
holder.image, dataList.get(position).getType());
convertImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, dataList.get(position).getBitmap());
}
return v;
}
}
Код Таска для конвертирования:
public class ConvertImageTask extends AsyncTask {
private static final String TAG = "WHALETAG";
Random random = new Random();
int timeout = random.nextInt(5)+2; // для искусственного замедления конвертации
private static final int TYPE_ROTATE = 0;
private static final int TYPE_INVERT = 1;
private static final int TYPE_MIRROR = 2;
private int type = -1;
ProgressBar bar;
ImageView image;
public ConvertImageTask(ProgressBar bar, ImageView imageView, int type) {
this.bar = bar;
this.image = imageView;
this.type = type;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
bar.setMax(timeout);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int i = values[0];
bar.setProgress(i);
}
@Override
protected Bitmap doInBackground(Bitmap... bitmaps) {
Bitmap bitmap = bitmaps[0];
switch(type){
case TYPE_ROTATE:
bitmap = rotateBitmap(bitmap);
break;
case TYPE_INVERT:
bitmap = invertBitmap(bitmap);
break;
case TYPE_MIRROR:
bitmap = mirrorBitmap(bitmap);
break;
}
// Искусственно замедляем конвертацию
for (int i=1; i<=timeout; i++) {
Log.d(TAG, "doInBackground: осталось " + (timeout-i));
try {
Thread.sleep(1000); // спим 1 секунду
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
Log.d(TAG, "onPostExecute: закончилась конвертация типа " + type);
bar.setVisibility(View.GONE);
image.setImageBitmap(bitmap);
image.setVisibility(View.VISIBLE);
}
скажите, может правильнее будет поступить так:
Запускать асинкТаск, передавая в него (битмап для обработки, адаптер)
Внутри асинкТаска получать конвертированный bitmap и отправлять его в список битмапов.
По завершении таска вызывать adapter.notifyDataSetChanged();
В адаптере устанавливать готовый полученный bitmap в его holder.imageView?
Вопрос только, как тогда обновлять progressBar по мере конвертирования?
Ответы
Ответ 1
Обнулите картинку в ImageView перед началом загрузки: if (holder.progressBar.getProgress() == 0 && holder.progressBar.getVisibility() == View.VISIBLE) { holder.image.setImageDrawable(null); //теперь запускайте скачивание }
Комментариев нет:
Отправить комментарий