Як працює метод getView () при створенні власного користувацького адаптера?


101

Мої запитання:

  1. Яка саме функція LayoutInflater?
  2. Чому всі статті, які я прочитав, перевіряють, чи не передусім перегляд перегляду недійсний чи не перший? Що це означає, коли вона є нульовою, і що це означає, коли її немає?
  3. Який батьківський параметр приймає цей метод?

Відповіді:


115

1: Графік LayoutInflaterбере ваш макет XML-файлів і створює різні об’єкти View з його вмісту.

2: Адаптери побудовані для повторного використання переглядів, коли перегляд прокручується так, що його більше не видно, його можна використовувати для одного з нових переглядів, що з’являються. Цей повторно використаний вид - це convertView. Якщо це недійсно, це означає, що перегляду не існує, і ми мусимо створити новий, інакше нам слід використовувати його, щоб уникнути створення нового.

3: Додано parent, щоб ви могли переповнити свій погляд на правильний параметр макета.

Все це разом можна використовувати для ефективного створення подання, яке з’явиться у вашому списку (або іншого виду, який займає адаптер):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Зверніть увагу на використання LayoutInflater, яке parentможе бути використане як аргумент для нього, і як convertViewйого повторно використовувати.


5
Convertview == null корисний, коли всі ваші шрифти дотримуються одного і того ж макета. Якщо вам потрібно перевірити, наприклад, радіо чи перевірену кнопку, і змінити макет залежно від кожного елемента, вам потрібно перевстановити або він отримає кешоване подання.
сагит

Не потрібно занадто переробляти. Просто потрібно записати перемикач або if-else сходинку в getview і надути перегляди відповідно до вашого випадку, замінити public int getItemViewType (int position) та public int getViewTypeCount (). @sagits
Prashanth Debbadwar

Якщо висловлювання зазвичай працюють, але при використанні радіо кнопок, редагуванні текстів і подібних матеріалів у мене виникли проблеми з використанням кешованих подань, є деякі запитання щодо цього матеріалу при переповненні стека.
сагит

71

getView()Спосіб адаптер для зору генеруючого елемента з ListView, Gallery...

  1. LayoutInflaterвикористовується , щоб отримати вид об'єкта , який ви визначаєте в макет XML (кореневої об'єкт, зазвичай LinearLayout, FrameLayoutабо RelativeLayout)

  2. convertViewпризначений для переробки. Скажімо, у вас є перегляд списку, який може відображати лише 10 елементів одночасно, і в даний час він відображає пункт 1 -> пункт 10. Коли ви прокручуєте один елемент вниз, елемент 1 буде поза екраном, і пункт 11 відобразиться . Для генерації View для елемента 11 буде викликано метод getView (), і convertViewось перегляд пункту 1 (який більше не потрібен). Тож натомість створіть новий об’єкт View для елемента 11 (що коштує дорого), чому б не повторно використовувати convertView? => ми просто перевіряємо, чи convertViewце нуль чи ні, якщо null створити новий перегляд, інакше повторно використовувати convertView.

  3. parentViewце ListView або Галерея ..., що містить представлення елемента, який getView()створюється.

Примітка : цей метод ви не називаєте безпосередньо, просто потрібно його реалізувати, щоб сказати батьківському виду, як створити подання елемента.


2
ЧУЖЕ пояснення для батьківView, не можу знайти кращого пояснення, ніж це, +1
Ахмед Адель Ісмаїл

Дивовижне пояснення!
Габі

чудове пояснення +1
tpk

8

Ви можете подивитися це відео про перегляд списку. Це з останніх років Google IO і досі найкращий перегляд списків у моєму розумі.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Він надуває макети (XML-файли у вашому res / layout / folder) у об'єкти Java, такі як LinearLayout та інші види.

  2. Перегляньте відео, ви дізнаєтесь про те, яким чином використовується перегляд перетворення, в основному його перегляд, який переробляється на очікуванні повторного використання вами, щоб уникнути створення нового об’єкта та уповільнення прокрутки списку.

  3. Дозволяє посилатися на перегляд списку з адаптера.


5

Яка саме функція LayoutInflater?

Коли ви проектуєте за допомогою XML, всі ваші користувальницькі елементи - це лише теги та параметри. Перш ніж використовувати ці елементи інтерфейсу (наприклад, TextView або LinearLayout), вам потрібно створити фактичні об'єкти, відповідні цим елементам xml. Саме для цього потрібна інфляція. Надувальник використовує ці теги та відповідні їм параметри для створення фактичних об'єктів та встановлення всіх параметрів. Після цього ви можете отримати посилання на елемент інтерфейсу, використовуючи findViewById ().

Чому всі статті, які я прочитав, перевіряють, чи не передусім перегляд перегляду недійсний чи не перший? Що це означає, коли вона є нульовою, і що це означає, коли її немає?

Це цікавий. Розумієте, виклик getView () викликається щоразу, коли елемент у списку малюється. Тепер, перш ніж елемент можна намалювати, його потрібно створити. Тепер в основному ConverView - це останній використаний вигляд для малювання елемента. У getView () ви спочатку надуваєте xml, а потім використовуєте findByViewID (), щоб отримати різні елементи інтерфейсу списку. Коли ми перевіряємо на (convertView == null), що ми робимо, це перевірити, що якщо подання є нульовим (для першого елемента), то створимо його, інакше, якщо воно вже існує, повторно його використовувати, не потрібно повторювати процес надуття ще раз . Це робить його набагато ефективнішим.

Ви, мабуть, також натрапили на концепцію ViewHolder у getView (). Це робить список більш ефективним. Ми робимо переглядач і зберігаємо посилання на всі елементи інтерфейсу, які ми отримали після надуття. Таким чином, ми можемо уникати виклику численних findByViewId () та економити багато часу. Цей ViewHolder створюється в (convertView == null) умові і зберігається в convertView за допомогою setTag (). У циклі else ми просто повертаємо його за допомогою getView () і повторно використовуємо його.

Який батьківський параметр приймає цей метод?

Батьківщина - це ViewGroup, до якого нарешті додається ваш погляд, створений getView (). Тепер у вашому випадку це буде ListView.

Сподіваюся, це допомагає :)


4
  1. Надуваючий надувальний макет надуває / додає зовнішній XML у ваш поточний вигляд.

  2. getView () викликається багато разів, у тому числі під час прокрутки. Тож якщо вона вже має перегляд завищеної, ми не хочемо робити це знову, оскільки надуття - це дорогий процес. Ось чому ми перевіряємо, чи є його нуль, а потім надуваємо.

  3. Батьківський погляд - це одна клітинка вашого списку ..


3
Тут викладено неправильно батьківський погляд. Це буде ListView не ListItem
Varun Jain

2

LayoutInflaterвикористовується для генерування динамічних представлень XML для ListViewелемента або onCreateViewфрагмента.

ConvertViewв основному використовується для переробки переглядів, які зараз не переглядаються. Скажіть, у вас є прокрутка ListView. Під час прокрутки вниз або вгору convertViewподається вид, який прокручувався. Така повторна використання економить пам’ять.

Батьківський параметр getView()методу дає посилання на батьківський макет, який має listView. Скажіть, що ви хочете отримати ідентифікатор будь-якого елемента в батьківській XML, який ви можете використовувати:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }

1

getView()створити новий Viewабо ViewGroupдля кожного рядка Listviewабо Spinner. Ви можете визначити це Viewабо ViewGroupу Layout XMLфайлі в res/layoutпапці і можете надати посилання на Adapterклас Object.

якщо у вас є 4 елементи в масиві, переданому Адаптеру. getView()метод створить 4 Перегляд для 4 рядів Adaper.

Клас LayoutInflater має метод inflate (), який створює View Object з макета ресурсів XML.


0

Ви також можете знайти корисну інформацію про getView в інтерфейсі Adapter у файлі Adapter.java. Він говорить;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.