Размещение элемента ListView в контейнере ScrollView

By | 05.03.2014

Разместить элемент ListView в контейнере ScrollView в одном Activity запрещается, как я понимаю потому, что оба эти контейнера имеют свой скрол, соответственно возникает конфликт. Хотя технически ошибки в приложении из-за этого не возникает. Это приводит к следующему: в ScrollView все непрокручиваемые элементы отображаются как и должны, а ListView отображает только одну строку результата, а остальные нужно прокручивать в самом ListView, но он имеет высоту только одного элемента, остальные скрываются. Мне пришло в голову, что можно было бы получить количество элементов ListView и задать его высоту в соответствии с этим количеством.

Итак код XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp" >
 
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" >
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hello_world" />
 
            <ListView
                android:id="@+id/listItems"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </ListView>
        </LinearLayout>
    </ScrollView>
 
</RelativeLayout>

Теперь код для изменения высоты:

// Изменение высоты ListView в зависимости от количества элементов, чтобы вместить в ScrollView
// в параметрах передаём listView для определения высоты
public void setListViewHeightBasedOnChildren(ListView listView) {
    ArrayAdapter listAdapter = (ArrayAdapter) listView.getAdapter(); 
 
    int totalHeight = 0;
    // проходимся по элементам коллекции
    for(int i = 0; i < listAdapter.getCount(); i++) {
      View listItem = listAdapter.getView(i, null, listView);
      listItem.measure(0, 0);
      // получаем высоту
      totalHeight += listItem.getMeasuredHeight();
    }
 
    // устанавливаем новую высоту для контейнера
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}

Ну и применение всего этого на деле:

// listItems это элемент ListView
setListViewHeightBasedOnChildren(listItems);