Объяснение метода getView() ArrayAdapter

Не могли бы вы объяснить getView() метод ArrayAdapter.

Я прочитал документы, и у него есть три параметра:

  • position: Позиция элемента в наборе данных адаптера элемента, представление которого мы хотим.
  • convertView: старый вид для повторного использования, если это возможно. Примечание. Перед использованием следует убедиться, что это представление не является нулевым и имеет соответствующий тип. Если невозможно преобразовать это представление для отображения правильных данных, этот метод может создать новое представление.
    Гетерогенные списки могут указывать количество типов представлений, чтобы это представление всегда имело правильный тип (см. getViewTypeCount( ) и getItemViewType(int)).
  • parent: родитель, к которому в конечном итоге будет присоединено это представление.

Я понял параметр position. Как они сказали, это подразумевает позицию элемента, просмотр которого был запрошен.

Откуда convertView. Я видел много примеров, где они проверяют, является ли convertView нулевым. Если is равно null, они раздувают новый экземпляр макета строки, заполняют его и возвращают. Думаю, я тоже обдумал это, но одна вещь все еще сбивает меня с толку. Какой макет передается через параметр convertView. Если resource, который передается при инициализации ArrayAdapter? Является ли кешированная копия последнего макета, возвращаемая getView()?

И наконец. Что делает параметр parent. Я не видел слишком много примеров, использующих это. Большинство из них просто повторно используют/раздувают макет строки и возвращают его.

(Я спрашиваю, потому что в моем ListView есть анимация по клику. В частности, это тот, который призван воспроизвести раскрывающееся меню быстрых действий Spotify. Моя анимация была немного вялой. После диагностики этой проблемы некоторое время я понял, что это произошло из-за того, что мой метод getView() занимает немного времени, так как я раздуваю новый макет строки на каждой итерации. Кто-то предложил кэшировать макет строки в ViewHolder, в то время как другие примеры указывают на повторное использование параметра convertView, т. е. раздувание макета строки только в том случае, если convertView равно нулю.)


person Mridang Agarwalla    schedule 13.09.2012    source источник


Ответы (2)


Является ли кэшированная копия последнего макета, возвращаемого getView()?

convertView — это представление строки, которая покинула экран (поэтому это не последнее представление, возвращаемое методом getView). Например, сначала показывается список, в данном случае convertView это null, ранее не было построено ни одного представления строки и оно покинуло экран. Если вы прокрутите вниз, строка 0 покинет экран (больше не будет видна), когда это произойдет, ListView может сохранить это представление в кеше, чтобы позже использовать его (это имеет смысл, поскольку строки ListView обычно имеют один и тот же макет, только данные разные). Причина хранения некоторых представлений в кеше и последующего их использования заключается в том, что метод getView может вызываться много раз (каждый раз, когда пользователь прокручивает вверх/вниз и на экране появляются новые строки). Если бы каждый раз нужно было воссоздавать представление строки, это привело бы к созданию большого количества объектов, чего следует избегать. В вашем методе getView вы должны проверить convertView, чтобы убедиться, что это null. Если это null, то вы должны создать новое представление строки и заполнить его данными, если это не null, ListView предложило вам предыдущее представление. Наличие этого предыдущего представления означает, что вам не нужно создавать новый макет строки, вместо этого вы должны заполнить его правильными данными, так как к этому кэшированному представлению все еще прикреплены старые данные (вы увидите много вопросов о stackoverflow, где пользователи спрашивают, почему строки их ListView дублируются при прокрутке вниз).

Что делает родительский параметр. Я не видел слишком много примеров, использующих это. Большинство из них просто повторно используют/раздувают макет строки и возвращают его.

Его следует использовать для получения правильного LayoutParams для вновь надутого/построенного ряда. Например, если вы раздуете макет, который имеет RelativeLayout в качестве корня, и вы не используете parent для получения LayoutParams, у вас могут возникнуть проблемы с макетом строки. Чтобы принять родителя во внимание, вы должны использовать:

convertView = getLayoutInflater().inflate(R.layout.row_layout, parent, false);
person user    schedule 13.09.2012
comment
Это действительно хороший ответ! - person Tarik; 25.08.2013
comment
лучший ответ tnx - person Mir Hussain; 26.06.2016

Насколько я понимаю convertView, это, по сути, представления, которые были переработаны, потому что они не используются в данный момент - например, вы прокручиваете список вниз, те, что вверху, не отображаются на экране, поэтому они передаются в этот параметр для использования, когда вам нужно новое представление (так что вам не нужно создавать совершенно новое представление, пока неиспользуемые не используются). В iOS есть аналогичный метод под названием dequeueReusableCellWithIdentifier. Если каждая строка вашего списка имеет одинаковую структуру, безопасно привести ее к соответствующему типу и просто обновить информацию в ней — текст, изображения и т. д. Это будет представление, которое ранее было возвращено вызовом getView() для того же список.

Мое лучшее предположение (и это, по общему признанию, предположение) с parent заключается в том, что это представление, дочерним элементом которого является этот список адаптера. Это дает вам обратный путь к системе рендеринга, если вам нужен контекст, доступ к системе ресурсов, чтобы передать информацию или получить информацию из родительского представления списка.

person Xono    schedule 13.09.2012