Подтвердить что ты не робот

Скрытие представления заголовка в ListView

Я пытаюсь добавить заголовок в свой список и скрыть его все время, пока мы не перейдем к нему (например, механизм pull-to-refresh). Проблема заключается в следующем: если список не достаточно высок, чтобы заполнить экран - представление заголовка отображается поверх списка.

Есть ли способ скрыть его и сделать видимым только при прокрутке? Я пробовал много вещей, но я не могу найти хороший и простой способ сделать это.

Спасибо

4b9b3361

Ответ 1

Здесь сообщение в блоге, описывающее простой способ скрытия и отображения заголовка.

Идея состоит в том, чтобы поместить содержимое, которое вы хотите скрыть, в LinearLayout, которое его обертывает и скрывает только контент. Таким образом, обертка LinearLayout рухнет, когда ее содержимое будет скрыто, что приведет к тому, что заголовок ViewView будет технически присутствовать, но 0dip выше.

Примечание. Если вы попытаетесь скрыть содержимое без прилагаемого макета, вы останетесь с нежелательным пространством в представлении заголовка.

Пример макета со счетчиком, представляющим контент:

<LinearLayout
      xmlns:a="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
      <ProgressBar
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

Затем вы можете скрыть счетчик (контент) следующим образом:

spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE);

Ответ 2

Вы можете посмотреть ListView.setOverscrollHeader() или ListView.setOverscrollFooter(). Это поведение, которое вы ищете?

Если нет, можете ли вы опубликовать какой-либо код, показывающий, что у вас есть до сих пор?

EDIT:

Хорошо, поэтому я просмотрел верхние и нижние колонтитулы Overscrolling, и вы правы, я не думаю, что вы вообще этого хотите.

Вместо этого вам следует, вероятно, взглянуть на механизм Pull to Refresh из приложения Twitter, которое другие пытались подражать. Вы можете посмотреть ответы на этот вопрос.

Самый многообещающий ответ кажется настраиваемым ListView, написанным Johan Nilson, код которого можно найти здесь:

https://github.com/johannilsson/android-pulltorefresh

РЕДАКТИРОВАТЬ № 2:

Я взглянул на пользовательский ListView PullToRefresh и то, что вы хотите сделать, возможно, возможно, хотя и не всегда легко. Позвольте мне объяснить.

PullToRefreshListView - это просто хак, который использует дополнительный заголовок в стандартных списках ListView. Скрытый "Pull To Refresh", который вы видите, на самом деле является только заголовком ListView. Когда список отображается, эта строка выполняется:

setSelection(1);

Это прокручивает список до первого элемента в списке, эффективно скрывая заголовок. Когда список достаточно короткий, чтобы отображать его полностью на экране, прокрутка не требуется, поэтому кнопка "Нажмите, чтобы обновить" .

Когда этот "Tap to Refresh" отображается, механизм pull to refresh отключен, но достаточно легко его исправить. Эффект pull to refresh достигается за счет увеличения верхнего заполнения заголовка, так что кажется, что вы вытягиваете список вниз (когда действительно более точно сказать, что заголовок нажимает остальную часть списка вниз).

Количество добавленных дополнений контролируется функцией applyHeaderPadding() в строке 199 исходного кода. В этой функции в строке 220 есть оператор if, который применяет только дополнение, когда список находится в режиме RELEASE_TO_REFRESH:

if (mRefreshState == RELEASE_TO_REFRESH)
{
    //Some code that eventually adds padding to the header...
}

Если вы устраните это условие или измените его на применение дополнения, независимо от того, в каком режиме вы находитесь, вы можете перетащить, чтобы обновить, даже если список короткий, а заголовок говорит "Нажмите, чтобы обновить"

if (true)
{
    //Some code that eventually adds padding to the header...
}

Однако это не точно создает эффект, который вы ищете. Если список короткий, его можно перетащить, чтобы обновить, но заголовок "Нажмите, чтобы обновить" все еще отображается. Теперь проблема заключается в следующем: "Как скрыть заголовок, пока не начнется движение перетаскивания?" Это сложная проблема, с ее помощью, с несколькими вопросами.

Если вы хотите заголовок, вы должны добавить его до того, как вы установите адаптер для ListView, иначе вы получите всевозможные ошибки.

У меня был некоторый успех в этом, но я не придумал ничего стабильного, потому что мое решение - это своего рода неприятный взлом поверх уже взломанного PullToRefreshListView. Я установил пустой FrameLayout в качестве заголовка и добавил исходное pull, чтобы обновить заголовок до этого макета кадра. Затем, когда я перетащил список, я отредактировал высоту в LayoutParameters рамочной компоновки, чтобы расти и сжиматься так же, как и исходное дополнение. Это вроде как сработало, но в конце концов закрепилось бы близко, и я еще не понял, почему еще.

В любом случае, если я получу его на работу, я отправлю код, иначе кто-то мудрее, чем я мог бы предложить решение на основе информации, которую я только что предоставил.

Ответ 3

Вот решение для текущего PullToRefreshListView (обновлено 4 ноября 2011 г.):
https://github.com/johannilsson/android-pulltorefresh

на основе заголовка "Скрытие заголовка":
http://pivotallabs.com/users/joe/blog/articles/1759-android-tidbits-6-22-2011-hiding-header-views

1) Скопируйте файл pull_to_refresh_header.xml из библиотеки res/layout в ваше приложение res/layout.

2) Отредактируйте приложение pull_to_refresh_header.xml. Оберните верхнюю часть RelativeLayout в LinearLayout, а затем снова заверните LinearLayout в RelativeLayout. Зачем? Самый верхний макет должен быть RelativeLayout, потому что то, что ожидалось в коде, макет второго уровня должен быть LinearLayout, потому что это единственный макет, который рушится с View.GONE. Маркер третьего уровня должен быть таким же, как оригинальный RelativeLayout верхнего уровня (кроме id), чтобы сохранить внешний вид.

3) Сохраните тот же самый идентификатор в верхней части RelativeLayout (pull_to_refresh_header), дайте LinearLayout второго уровня по вашему выбору, дайте третьему уровню RelativeLayout другой идентификатор (например, pull_to_refresh_header2).

4) Переместите все отступы от верхнего RelativeLayout ко второму RelativeLayout.

5) В вашем коде используйте findViewById и ваш идентификатор LinearLayout, чтобы установить видимость в View.GONE. LinearLayout рухнет, и если вы переместили все значения дополнения на внутренний RelativeLayout, заголовок не должен занимать места вообще.