Использование ListAdapter для заполнения LinearLayout внутри макета ScrollView

Я столкнулся с очень распространенной проблемой: я выложил действие, и теперь выясняется, что в этом ScrollView должно отображаться несколько элементов. Обычный способ сделать это – использовать существующий ListAdapter , подключить его к ListView и BOOM, чтобы у меня был список элементов.

НО Вы не должны помещать в ListView в ScrollView поскольку он закручивает прокрутку – даже Android Lint жалуется на это.

Итак, вот мой вопрос:

Как подключить ListAdapter к LinearLayout или что-то подобное?

Я знаю, что это решение не будет масштабироваться для множества элементов, но мои списки очень короткие (<10 элементов), поэтому повторное использование просмотров на самом деле не требуется. Я LinearLayout я могу жить с размещением всех представлений непосредственно в LinearLayout .

Одним из решений, которое я придумал, было бы разместить мой существующий макет действий в секции headerView ListView . Но это похоже на злоупотребление этим механизмом, поэтому я ищу более чистое решение.

Идеи?

ОБНОВЛЕНИЕ: Чтобы вдохновить правильное направление, я добавляю образец макета, чтобы показать свою проблему:

             

ОБНОВЛЕНИЕ 2 Я изменил заголовок, чтобы было легче понять (получило понижение, да!).

Вероятно, вы должны просто вручную добавить свои элементы в LinearLayout :

 LinearLayout layout = ... // Your linear layout. ListAdapter adapter = ... // Your adapter. final int adapterCount = adapter.getCount(); for (int i = 0; i < adapterCount; i++) { View item = adapter.getView(i, null, null); layout.addView(item); } 

EDIT : я отклонил этот подход, когда мне нужно было отобразить около 200 нетривиальных элементов списка, это очень медленно - для Nexus 4 понадобилось около 2 секунд, чтобы отобразить мой «список», что было неприемлемым. Поэтому я обратился к подходу Фло с заголовками. Он работает намного быстрее, потому что представления списков создаются по требованию, когда пользователь прокручивается, а не во время создания представления.

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

Пример. В основном макет активности (или fragmentа) преобразуется в нечто подобное (больше не требуется ScrollView):

  

Затем в onCreateView() (я буду использовать пример с fragmentом) вам нужно добавить представление заголовка, а затем установить адаптер (я предполагаю, что идентификатор ресурса заголовка - header_layout ):

 ListView listView = (ListView) inflater.inflate(R.layout.my_top_layout, container, false); View header = inflater.inflate(R.layout.header_layout, null); // Initialize your header here. listView.addHeaderView(header, null, false); BaseAdapter adapter = // ... Initialize your adapter. listView.setAdapter(adapter); // Just as a bonus - if you want to do something with your list items: view.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { // You can just use listView instead of parent casted to ListView. if (position >= ((ListView) parent).getHeaderViewsCount()) { // Note the usage of getItemAtPosition() instead of adapter's getItem() because // the latter does not take into account the header (which has position 0). Object obj = parent.getItemAtPosition(position); // Do something with your object. } } }); 

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

Очевидно, что «элемент детали» более динамичен, чем статический (изменение количества элементов по сравнению с количеством элементов фида и т. Д.), Иначе вы вообще не будете думать об использовании адаптера. Поэтому, когда вам нужен адаптер, используйте ListView.

Реализация решения, которое заполняет LinearLayout из адаптера, в конечном итоге не что иное, как создание ListView с настраиваемой компоновкой.

Только мои 2 цента.

Установите свой вид на main.xml onCreate, а затем надуйте его из row.xml

main.xml

        

row.xml

      

Я использую следующий код, который реплицирует функциональность адаптера с помощью ViewGroup и TabLayout . Хорошо, что если вы измените свой список и снова привяжете его, это повлияет только на измененные элементы:

Применение:

 val list = mutableListOf() layout.bindChildren(list, { it.personId }, { bindView(it) }, {d, t ->bindView(d, t)}) list.removeAt(0) list+=newPerson layout.bindChildren(list, { it.personId }, { bindView(it) }, {d, t ->bindView(d, t)}) 

Для ViewGroups :

 fun  ViewGroup.bindChildren(items: List, id: (Item) -> Key, view: (Item) -> View, bind: (Item, View) -> Unit) { val old = children.map { it.tag as Key }.toList().filter { it != null } val new = items.map(id) val add = new - old val remove = old - new val keep = new.intersect(old) val tagToChildren = children.associateBy { it.tag as Key } val idToItem = items.associateBy(id) remove.forEach { tagToChildren[it].let { removeView(it) } } keep.forEach { bind(idToItem[it]!!, tagToChildren[it]!!) } add.forEach { id -> view(idToItem[id]!!).also { it.tag = id }.also { addView(it, items.indexOf(idToItem[id])) } } } 

Для TabLayout меня есть следующее:

 fun  TabLayout.bindTabs(items: List, toKey: (Item) -> Key, tab: (Item) -> TabLayout.Tab, bind: (Item, TabLayout.Tab) -> Unit) { val old = (0 until tabCount).map { getTabAt(it)?.tag as Key } val new = items.map(toKey) val add = new - old val remove = old - new val keep = new.intersect(old) val tagToChildren = (0 until tabCount).map { getTabAt(it) }.associateBy { it?.tag as Key } val idToItem = items.associateBy(toKey) remove.forEach { tagToChildren[it].let { removeTab(it) } } keep.forEach { bind(idToItem[it]!!, tagToChildren[it]!!) } add.forEach { key -> tab(idToItem[key]!!).also { it.tag = key }.also { addTab(it, items.indexOf(idToItem[key])) } } } 
  • Gridview с двумя столбцами и изображениями с автоматическим изменением размера
  • Как настроить Spinner в Android
  • Как избежать проблем при встраивании TForm в другой TForm?
  • Макет сообщения Whatsapp - Как получить представление времени в той же строке
  • Как добавить символ маркера в TextView?
  • Передача событий касания к родительскому виду
  • Как показать круговой текст с помощью TextView в Android
  • Повторное использование просмотров в Android Listview с двумя различными макетами
  • Java GUI-слушатели без AWT
  • Как создать EditText принимает Alphabets только в android?
  • Интервал между элементами ListView Android
  • Interesting Posts

    Разрешение отклонено при использовании mv в Windows 7 Cygwin

    Как использовать AOP с AspectJ для ведения журнала?

    Gson: Как исключить определенные поля из сериализации без аннотаций

    void_t “может реализовать концепции”?

    WPF: установка ширины (и высоты) в процентах

    Смогу ли я обновить семестр разработчика Snow Leopard до финала, или мне придется переустанавливать?

    Автозаполнение текстового поля в WPF

    Как использовать Json.NET для JSON-моделирования в проекте MVC5?

    Наименьшее изображение URI данных для прозрачного изображения

    Изменение видимого нижнего колонтитула на страницах каталога Apache

    Какие компьютерные компоненты в настоящее время уязвимы для магнитов?

    Как отключить кеширование на стороне клиента и прокси в ASP.NET MVC?

    Программно отображает представление из подключаемого модуля Eclipse

    Есть ли способ получить «защищенный» элемент другого объекта из производного типа?

    Объект X classа Y не реализует методSignatureForSelector в Swift

    Давайте будем гением компьютера.