Страницы

Поиск по вопросам

суббота, 4 апреля 2020 г.

ImageView и ProgressTab в ListView

#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); //теперь запускайте скачивание }

Комментариев нет:

Отправить комментарий