Первым побуждением было сделать то, что вынесено в заголовок: поместить ListView внутрь ScrollView. Получившаяся штука отображалась некорректно, что заставило меня зарыться поглубже в гугл.
Во многих местах в сети (например, тут: https://groups.google.com/forum/#!topic/android-beginners/LRpLgGOy2Pc или тут: http://stackoverflow.com/questions/1526831/android-scrollview-layout-problem) напрямую говорится о том, что так делать нельзя. Для реализации таких вещей у ListView предусмотрены штатные заголовки (headers).
Добавление заголовков производится вызовом метода класса ListView:
public void addHeaderView (View v)где View v можно создавать любым способом (или явным вызовом конструктора, или через inflater).
View hv = ...;
listView.addHeaderView(hv);
Заголовков у ListView может быть больше одного. С их количеством, кстати, связана ещё одна особенность: по умолчанию заголовки тоже кликабельны, как и обычные элементы списка, клик на них вызывает отработку лиснеров, заданных вызовами setOnItemClickListener и setOnItemLongClickListener, так что позиция кликнутого элемента, которая передаётся в лиснеры в параметре position, будет смещена на количество заголовков. Этот факт нужно обязательно учитывать в лиснерах при обработке. Для этого у ListView есть метод:
int getHeaderViewsCount()который возвращает количество заголовков списка. На значение, которое он возвращает, можно, например, уменьшить значение position, полученное в лиснере, перед позиционированием во внутреннем списке данных.
protected OnItemClickListener itemClickListener = new OnItemClickListener() {
public void onItemClick(final AdapterView<?> l, final View v, final int position, final long id) {
MyItem myItem = myItems.get(position - listView.getHeaderViewsCount());
// do something to myItem
}
};
Существует ещё один метод для добавления заголовков, чуть более сложный:
public void addHeaderView (View v, Object data, boolean isSelectable)Он предоставляет возможность сделать заголовок некликабельным: если в третий параметр передать false, то при клике на заголовок не будет отрабатывать onItemClickListener списка. Лиснеры же, заданные для views, расположенных внутри такого заголовка, будут отрабатывать штатно. Однако, даже в этом случае, несмотря на некликабельность заголовка, нумерация элементов для position всё равно будет учитывать их наличие.
View hv = ...;
listView.addHeaderView(hv, null, false);
Для полноты изложения скажу, что вторым параметром (Object data), смысл которого не очень понятен из документации, на самом деле задаются данные, которые будут возвращаться методом Adapter.getItem() (взято тут: http://stackoverflow.com/questions/4311693/what-does-the-second-parameter-in-addheaderview-in-the-class-listview-do).
Аналогичный набор методов есть у списка и для футеров (footers):
void addFooterView(View v)void addFooterView(View v, Object data, boolean isSelectable)int getFooterViewsCount()
