Подтвердить что ты не робот

Знать, когда View в ListView ушел с экрана?

У меня есть Googled это, но не могу найти ответ, поэтому здесь идет...

У меня есть ListView, который отображает некоторый текст и изображение. Базовый адаптер перерабатывает представления по соображениям производительности (согласно рекомендуемому подходу), и я загружаю изображения с помощью AsynchTask в соответствии с рекомендацией, найденной

4b9b3361

Ответ 1

Не могу поверить, насколько я был глуп, это очень простой лайнер для решения!

Как правило, в моем адаптере, если просмотр перекодируется, мне просто нужно обнулить растровое изображение ImageView перед повторным использованием представления. Это означает, что изображение в элементе списка будет пустым перед загрузкой следующего изображения. У меня больше нет проблемы с тем, что старый образ находится там, в то время как новое изображение загружается в фоновом режиме.

Я также внес изменения в адаптер, который отменяет любую текущую AsynchTask, связанную с представлением, которое может по-прежнему загружать предыдущее изображение, которое больше не требуется. Это было очень распространено, когда я очень быстро прокручивал представление списка, часто поддерживая резервную копию двух или более изображений, поэтому изображение будет меняться несколько раз, прежде чем устанавливать правильное изображение.

Вот новый код, с комментариями изменений, чтобы вы могли видеть, что происходит:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    ListViewHolder viewHolder;

    // if this is not a recycled view then create a new view for the data...
    if (convertView == null)
    {
        convertView = this.inflater.inflate(R.layout.target_list_view_layout, null, true);

        viewHolder = new ListViewHolder();

        viewHolder.manufacturer = (TextView) convertView.findViewById(R.id.manufacturer);
        viewHolder.targetName = (TextView) convertView.findViewById(R.id.targetName);
        viewHolder.targetThumbnail = (ImageView) convertView.findViewById(R.id.targetThumbnail);

        convertView.setTag(viewHolder);
    } else
    {
        viewHolder = (ListViewHolder) convertView.getTag();

        // Cancel the previous attempt to load an image as this is going to be superceded by the next image
        viewHolder.loadImageViewAsynchTask.cancel(true);

        // Clear down the old image so when this view is displayed, the user does not see the old image before the
        // new image has a chance to load in the background
        viewHolder.targetThumbnail.setImageBitmap(null);
    }

    TargetDescriptor targetDescriptor = this.selectedTargets.get(position);

    viewHolder.manufacturer.setText(targetDescriptor.manufacturer);
    viewHolder.targetName.setText(targetDescriptor.targetName);

    LoadImageViewAsynchTask loadImageViewAsynchTask = new LoadImageViewAsynchTask(viewHolder.targetThumbnail);
    loadImageViewAsynchTask.setTargetDescriptor(targetDescriptor);
    loadImageViewAsynchTask.execute(new Integer[]
    { 64, 64 });

    // Keep a reference to the task so we can cancel it if the view is recycled next time round to prevent
    // un-neccessary image loads that are out of date
    viewHolder.loadImageViewAsynchTask = loadImageViewAsynchTask;

    return convertView;
}

Ответ 2

На самом деле существует более простой способ сделать это, вы можете использовать прослушиватель:

mListView.setRecyclerListener(new AbsListView.RecyclerListener() {
@Override
    public void onMovedToScrapHeap(View view) {
  }
});

Ответ 3

Если вы используете LruCache для растровых изображений и каждый вид в списке просматривает ключ к элементу LruCache, вы можете лучше контролировать его. Затем в getView вы сначала попытаетесь получить растровое изображение из LruCache и только загрузите его снова, если его там нет.

Кроме того, вы можете установить setOnScrollListener() в ListView и использовать свой параметр visibleItemCount для настройки размера LruCache при первом прокрутке пользователя.

Ответ 4

если вы используете переопределенный метод getView для отображения изображений, чтобы вы могли проверить convertView. если оно было нулевым, то вы можете обнаружить, что оно переработано или оно не инициализировано ранее. просто вот так:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder viewholder;
    if (convertView == null) {
        viewholder = new ViewHolder();
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.item_row, parent, false);
        viewholder.tvID = (TextView) convertView.findViewById(R.id.tvID);
        viewholder.tvName = (TextView) convertView.findViewById(R.id.tvName);
        viewholder.tvFamily = (TextView) convertView.findViewById(R.id.tvFamily);
        viewholder.ivMain = (ImageView) convertView.findViewById(R.id.ivMain);
    } else {
        viewholder = (ViewHolder) convertView.getTag();
    }
    viewholder.tvID.setText(IDs[position]);
    viewholder.tvName.setText(Names[position]);
    viewholder.tvFamily.setText(Familys[position]);
    viewholder.ivMain.setImageResource(Images[position]);
    convertView.setTag(viewholder);
    return convertView;
}