2015-05-09 6 views
0

Я создал адаптер для ListView, который имеет два типа строк. ListView имеет 4 строки. Последняя строка имеет разный макет, поэтому я использую метод GetItemViewType в getview.Понимание шаблона ViewHolder

Я пытаюсь понять, как работает шаблон. Я наблюдал за этим: https://www.youtube.com/watch?v=bWsWe9T9HJw, чтобы получить лучшее понимание того, как работает переработка

Что я не понимаю: когда я прокрутки вниз в моем ListView, то convertview всегда нуль. Когда я снова прокручиваю резервную копию, convertview не является нулевым и может использоваться повторно.

Нельзя ли преобразовать view только null для первого элемента в списке? я не понимаю, почему это нуль для каждого нового элемента?

public override View GetView (int position, View convertView, ViewGroup parent) 
    { 
     BaseBundelVO bundle = _bundles [position]; 

     DSBundleListItem bundleHolder = null; 
     DSBundleArchiveItem archiveHolder = null; 

     int type = GetItemViewType(position); 
     if (convertView == null) 
     { 
      bundleHolder = new DSBundleListItem (_activity); 
      archiveHolder = new DSBundleArchiveItem (_activity); 

      switch (type) 
      { 
      case 0: 
       convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleListItem, null); 
       bundleHolder.IconIv = convertView.FindViewById<ImageView> (Resource.Id.iconIv); 
       bundleHolder.CoverIv = convertView.FindViewById<ImageView> (Resource.Id.coverIv); 
       bundleHolder.CoverTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverTitleTv); 
       bundleHolder.CoverSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverSubTitleTv); 
       bundleHolder.BundleProgress = convertView.FindViewById<ProgressBar> (Resource.Id.bundleProgress); 
       convertView.Tag = bundleHolder; 
       break; 
      case 1: 
       convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleArchiveItem, null); 
       archiveHolder.ArchiveTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveTitleTv); 
       archiveHolder.ArchiveSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveSubTitleTv); 
       convertView.Tag = archiveHolder; 
       break; 
      } 

     } 
     else 
     { 
      switch (type) 
      { 
      case 0: 
       bundleHolder = (DSBundleListItem)convertView.Tag; 
       Console.WriteLine (bundleHolder.IsDisposed()); 
       bundleHolder.RemoveImageLoaderCallBack(); 
      break; 
      case 1: 
       archiveHolder = (DSBundleArchiveItem)convertView.Tag; 
       Console.WriteLine (archiveHolder.IsDisposed()); 
       archiveHolder.RemoveImageLoaderCallBack(); 
      break; 
      } 
     } 

     switch (type) 
     { 
     case 0: 
      bundleHolder.CoverTitleTv.Text = bundle.Title; 
      bundleHolder.CoverSubTitleTv.Text = bundle.SubTitle; 
      bundleHolder.LoadImage(bundle.CoverImageLocation,bundle.Icon); 
      break; 
     case 1: 
      archiveHolder.ArchiveTitleTv.Text = "Archief"; 
      archiveHolder.ArchiveSubTitleTv.Text = "Bekijk onze eerder verschenen publicaties"; 
      break; 
     } 

     return convertView; 
    } 
+0

Если ваш экран может поместиться, скажем, 2 вида, то андроид загрузит представление вверх, 2 видимых вида и следующее представление внизу, так что ему нужно как минимум 4 вида. Это объясняет, почему это не только first convertview null. Btw FIY вы должны проверить новый RecyclerView с Api 21. –

ответ

1

не должны convertview быть пустым только для первого элемента в списке?

Не обычно.

Предположим, что эти 8 строк видны в ListView. Это означает, что ListView вызовет getView() не менее 8 раз с null для параметра convertView, чтобы заполнить видимое пространство в ListView.

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

Кроме того, в вашем случае для каждого вида видения существуют отдельные пулы объектов.

Если у вашего адаптера достаточно материала, в конце концов, вы в конце концов переработаете даже во время первоначального прокрутки вниз. Все зависит от размера строк, значений, которые адаптер возвращает от getCount() и т. Д.

Обратите внимание, что это не имеет ничего общего с шаблоном держателя вида.

+0

Я попытался добавить больше элементов в список, и теперь они перерабатываются, поэтому это означает, что вы были правы в отношении утилизации адаптера после определенного количества выделенной памяти – Joske369

0

View, который передан вам в этом методе, является фактическим View, который отображается в списке (или null, если вам нужно его создать).

Если ваш список достаточно высок, чтобы показать 6 предметов, например, он должен иметь по крайней мере 6 экземпляров в своем распоряжении! При прокрутке, однако, один из View выходит из окна и может быть повторно использован для другой стороны списка.

Это имеет смысл для вас?

+0

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