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

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

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

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

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

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

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

Идеи?

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

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/news_detail_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:visibility="visible"> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FFF" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingLeft="@dimen/news_detail_layout_side_padding" android:paddingRight="@dimen/news_detail_layout_side_padding" android:paddingTop="@dimen/news_detail_layout_vertical_padding" android:paddingBottom="@dimen/news_detail_layout_vertical_padding" > <TextView android:id="@+id/news_detail_date" android:layout_height="wrap_content" android:layout_width="fill_parent" android:gravity="center_horizontal" android:text="LALALA" android:textSize="@dimen/news_detail_date_height" android:textColor="@color/font_black" /> <Gallery android:id="@+id/news_detail_image" android:layout_height="wrap_content" android:layout_width="fill_parent" android:paddingTop="5dip" android:paddingBottom="5dip" /> <TextView android:id="@+id/news_detail_headline" android:layout_height="wrap_content" android:layout_width="fill_parent" android:gravity="center_horizontal" android:text="Some awesome headline" android:textSize="@dimen/news_detail_headline_height" android:textColor="@color/font_black" android:paddingTop="@dimen/news_detail_headline_paddingTop" android:paddingBottom="@dimen/news_detail_headline_paddingBottom" /> <TextView android:id="@+id/news_detail_content" android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="Here comes a lot of text so the scrollview is really needed." android:textSize="@dimen/news_detail_content_height" android:textColor="@color/font_black" /> <!--- HERE I NEED THE LIST OF ITEMS PROVIDED BY THE EXISTING ADAPTER. They should be positioned at the end of the content, so making the scrollview smaller is not an option. ----> </LinearLayout> </ScrollView> </LinearLayout> 

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

Solutions Collecting From Web of "Использование ListAdapter для заполнения LinearLayout внутри макета ScrollView"

Вероятно, вы должны просто вручную добавить свои объекты в 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 просмотров или более, я советую использовать подход заголовка.

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

 <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/my_top_layout" android:layout_width="fill_parent" android:layout_height="fill_parent"/> 

Затем в onCreateView() (я буду использовать пример с фрагментом) вам нужно добавить представление заголовка, а затем установить адаптер (я предполагаю, что идентификатор ресурса заголовка – 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

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="450dp" > <ListView android:id="@+id/mainListView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/size" android:layout_below="@+id/editText1" android:gravity="fill_vertical|fill_horizontal" android:horizontalSpacing="15dp" android:isScrollContainer="true" android:numColumns="1" android:padding="5dp" android:scrollbars="vertical" android:smoothScrollbar="true" android:stretchMode="columnWidth" > </ListView> <TextView android:id="@+id/size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:background="#ff444444" android:gravity="center" android:text="TextView" android:textColor="#D3D3D3" android:textStyle="italic" /> </EditText> </RelativeLayout> 

row.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingTop="3dp"> <TextView android:id="@+id/rowTextView" android:layout_width="0dip" android:layout_height="41dp" android:layout_margin="4dp" android:layout_weight="2.83" android:ellipsize="end" android:gravity="center_vertical" android:lines="1" android:text="John Doe" android:textColor="@color/color_white" android:textSize="23dp" > </TextView> </LinearLayout>