2013-04-09 1 views
9

У меня возникла неясная проблема, связанная с переработкой представлений в методе getView адаптера адаптера.Переработка видов в адаптере адаптера: как именно это обрабатывается?

Я понимаю, что элементы используются повторно, но как я могу точно знать, что реализовать в первой части инструкции if, а что во втором?

Сейчас у меня есть следующий код. Я пришел к этому вопросу из-за удаления кода во второй части инструкции, которая приводит к списку первых 9 элементов, которые повторяются число раз, а не все элементы. Я действительно не знал, что именно вызывает это ...

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row = convertView; 

     if (row == null) { 
      LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      title = getItem(position).getTitle(); 
      size = calculateFileSize(position); 

      txtTitle = (TextView) row.findViewById(R.id.txtTitle); 
      tvFileSize = (TextView) row.findViewById(R.id.tvFileSize); 

      txtTitle.setText(title); 
      tvFileSize.setText(size); 

     } else { 

      title = getItem(position).getTitle(); 
      size = calculateFileSize(position); 

      txtTitle = (TextView) row.findViewById(R.id.txtTitle); 
      tvFileSize = (TextView) row.findViewById(R.id.tvFileSize); 

      txtTitle.setText(title); 
      tvFileSize.setText(size); 
     } 

     return row; 
    } 
+0

Спасибо всем за быстрое и хорошее объяснение ! Получил некоторое чтение/наблюдение, чтобы сделать :) Очень ценю это! –

+0

Возможный дубликат [почему работает ViewHolder pattren?] (Http://stackoverflow.com/questions/5973917/why-does-the-viewholder-pattren-work) –

ответ

13

Я понимаю, что элементы повторно, но, как я знаю, что точный реализовать в первой части, если заявление, и что во втором?

Организация довольно проста, как только вы получите повесить его:

public View getView(int position, View convertView, ViewGroup parent) { 

    if (convertView == null) { 
     /* This is where you initialize new rows, by: 
     * - Inflating the layout, 
     * - Instantiating the ViewHolder, 
     * - And defining any characteristics that are consistent for every row */ 
    } else { 
     /* Fetch data already in the row layout, 
     * primarily you only use this to get a copy of the ViewHolder */ 
    } 

    /* Set the data that changes in each row, like `title` and `size` 
    * This is where you give rows there unique values. */ 

    return convertView; 
} 

Подробные объяснения того, как работает RecycleBin ListView и почему ViewHolders важны часы Turbo Charge your UI, презентации Google I/O с помощью андроида ведущих программистов ListView.

+0

Great Link, Сэм! Я собирался опубликовать это, пока не увидел, что ты это сделал. Я впервые узнал об этом от вас здесь, и это было удивительно полезно. Благодаря! – codeMagic

+0

Спасибо, это для меня. Вы также можете опубликовать его или даже последующую презентацию «World of ListView». Из презентаций ввода-вывода есть чему поучиться. – Sam

+0

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

15

Это легко. В первый раз, когда не создается ни одна строка, вы должны раздувать их. После этого ОС os могут решить переработать просмотренные вами представления и которые больше не видны. Они уже завышены и переданы в параметр convertView, поэтому вам нужно всего лишь организовать его, чтобы показать новый текущий элемент, например, помещая правильные значения в различные текстовые поля.

enter image description here

Короче говоря, в первой части, вы должны выполнить инфляцию и заполнить значения, во втором случае (if convertView != null) следует перезаписать только поле, потому что, учитывая мнение было повторно, то TextViews содержат значения старого элемента.

This post и this являются хорошими отправными точками

+0

+1 для диаграммы –

4

Я бы рекомендовал вам использовать держатель View и шаблон convertview для создания вашего спискаView, поскольку он будет более эффективным. Here - хорошее объяснение того, как оно работает с стратегией повторного использования. Это ответит на ваш вопрос о том, как работает рециклинг. Если вы хотите обратиться к образцу кода, у меня его есть на GitHub.

Надеюсь, это поможет.

1

Последняя часть вопроса, которую я действительно не мог понять без картины эффекта, но для первой части «что реализовать в первой части инструкции if, а что во втором« Я думаю, что я », Мы обнаружили, что эта реализация очень распространена.

Сначала вы найдете ссылки на изображения и сохраните их в статическом классе ViewHolder, который затем присоединяется к тегу нового завышенного представления. Поскольку listview перерабатывает представления и отправляется convertView, вы получаете ViewHolder из тега convertView, поэтому вам не нужно снова искать ссылки (что значительно повышает производительность) заданное положение.

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

@Override 
public View getView(int position, View convertView, ViewGroup container) { 
    ViewHolder holder; 
    Store store = getItem(position); 
    if (convertView == null) { 
     convertView = mLayoutInflater.inflate(R.layout.item_store, null); 

     // create a holder to store references 
     holder = new ViewHolder(); 

     // find references and store in holder 
     ViewGroup logoPhoneLayout = (ViewGroup) convertView 
       .findViewById(R.id.logophonelayout); 
     ViewGroup addressLayout = (ViewGroup) convertView 
       .findViewById(R.id.addresslayout); 

     holder.image = (ImageView) logoPhoneLayout 
       .findViewById(R.id.image1); 
     holder.phone = (TextView) logoPhoneLayout 
       .findViewById(R.id.textview1); 
     holder.address = (TextView) addressLayout 
       .findViewById(R.id.textview1); 

     // store holder in views tag 
     convertView.setTag(holder); 
    } else { 

     // Retrieve holder from view 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    // fill in view with our store (at this position) 
    holder.phone.setText(store.phone); 
    holder.address.setText(store.getFullAddress()); 

    UrlImageViewHelper.setUrlDrawable(holder.image, store.storeLogoURL, 
      R.drawable.no_image); 

    return convertView; 
} 

private static class ViewHolder { 
    ImageView image; 
    TextView phone; 
    TextView address; 
} 
5

Вы хотите создать ViewHolder класс в вашем MainActivity. Что-то вроде

static class ViewHolder 
    { 
     TextView tv1; 
     TextView tv2; 
    } 

затем в вашем getView, первый раз, когда вы получите ваш Views от вашего XML в if и использовать их после того, что в else

View rowView = convertView; 
     if (rowView == null) 
     { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      rowView = inflater.inflate(R.layout.layout_name_to_inflate, parent, false); 
      holder = new ViewHolder(); 
      holder.tv1= (TextView) rowView.findViewById(R.id.textView1); 
      holder.tv2 = (RadioGroup) rowView.findViewById(R.id.textView2);    
      rowView.setTag(holder); 
     } 
     else 
     { 
      holder = (ViewHolder) rowView.getTag(); 
     } 

 Смежные вопросы

  • Нет связанных вопросов^_^