Я искал решения этой проблемы, и единственный ответ, который я могу найти, - « не помещайте ListView в ScrollView ». Мне еще предстоит увидеть какое-либо реальное объяснение того, почему . Кажется, единственная причина, по которой я могу найти это, заключается в том, что Google не считает, что вам следует этого делать. Ну, я так и сделал.
Итак, вопрос в том, как вы можете поместить ListView в ScrollView, не сворачивая его до минимальной высоты?
ListView
.ListView
может иметь несколько стилей строк, а также строки, которые нельзя выбрать.Ответы:
Использование,
ListView
чтобы сделать это не прокрутка очень дорого и идет против всей целиListView
. Вы должны НЕ делать этого. Просто используйтеLinearLayout
вместо этого.источник
How can I put a ListView into a ScrollView without it collapsing?
... Вы можете сказать, что вы не должны это делать, но также дать ответ о том, как это сделать, это хороший ответ. Вы знаете, что ListView имеет некоторые другие интересные функции, помимо прокрутки, функции, которых у LinearLayout нет.Вот мое решение. Я довольно новичок в платформе Android, и я уверен, что это немного хакерски, особенно в части, касающейся прямого вызова .measure и прямой установки
LayoutParams.height
свойства, но это работает.Все, что вам нужно сделать, это позвонить,
Utility.setListViewHeightBasedOnChildren(yourListView)
и он будет изменен, чтобы точно соответствовать высоте его предметов.источник
LinearLayout
не обладает всеми присущими ему тонкостями aListView
- у него нет разделителей, представлений верхнего / нижнего колонтитула, селектора списка, который соответствует цветам тем пользовательского интерфейса телефона, и т. Д. Честно говоря, нет причин, по которым вы не можете прокручивать внутренний контейнер, пока он не достигнет конца, а затем перестанет перехватывать события касания, чтобы прокручивать внешний контейнер. Каждый настольный браузер делает это, когда вы используете колесо прокрутки. Сам Android может справиться с вложенной прокруткой, если вы перемещаетесь с помощью трекбола, так почему бы не с помощью касания?listItem.measure(0,0)
сгенерирует NPE, если listItem является экземпляром ViewGroup. Я добавил следующееlistItem.measure
:if (listItem instanceof ViewGroup) listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
ListView
может содержать элементы переменной высоты. ВызовgetMeasuredHeight()
только возвращает целевую минимальную высоту, а не фактическую высоту. Я попытался использоватьgetHeight()
вместо этого, но это возвращает 0. У кого-нибудь есть понимание того, как подойти к этому?Это определенно сработает ............
Вы должны просто заменить свой
<ScrollView ></ScrollView>
XML-файл в макетеCustom ScrollView
следующим образом<com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
источник
Помещенный
ListView
внутрьScrollView
, мы можем использоватьListView
какScrollView
. Вещи, которые должны быть в,ListView
могут быть помещены внутрьListView
. Другие макеты сверху и снизуListView
можно поместить, добавив макеты в верхний и нижний колонтитулыListView
. Таким образом, весьListView
даст вам опыт прокрутки.источник
Существует множество ситуаций, в которых имеет смысл иметь ListView в ScrollView.
Вот код, основанный на предложении Дуга: он работает фрагментом, занимает меньше памяти.
вызовите setListViewHeightBasedOnChildren (listview) для каждого встроенного списка.
источник
На самом деле ListView уже способен измерять себя достаточно высоко, чтобы отображать все элементы, но он этого не делает, когда вы просто указываете wrap_content (MeasureSpec.UNSPECIFIED). Это будет сделано, когда задана высота с MeasureSpec.AT_MOST. Обладая этими знаниями, вы можете создать очень простой подкласс для решения этой проблемы, который работает намного лучше, чем любое из решений, опубликованных выше. Вы все еще должны использовать wrap_content с этим подклассом.
Манипулирование heightMeasureSpec для AT_MOST с очень большим размером (Integer.MAX_VALUE >> 4) заставляет ListView измерять все свои дочерние элементы до заданной (очень большой) высоты и соответственно устанавливать его высоту.
Это работает лучше, чем другие решения по нескольким причинам:
С другой стороны, вы можете утверждать, что это зависит от недокументированного поведения в SDK, которое может измениться. С другой стороны, вы можете утверждать, что именно так wrap_content должен действительно работать с ListView и что текущее поведение wrap_content просто нарушено.
Если вы обеспокоены тем, что в будущем поведение может измениться, вам просто нужно скопировать функцию onMeasure и связанные с ней функции из ListView.java в свой собственный подкласс, а затем запустить путь AT_MOST через onMeasure для UNSPECIFIED.
Кстати, я считаю, что это совершенно правильный подход, когда вы работаете с небольшим количеством элементов списка. Это может быть неэффективно по сравнению с LinearLayout, но когда количество элементов мало, использование LinearLayout является ненужной оптимизацией и, следовательно, ненужной сложностью.
источник
Для этого есть встроенная настройка. На ScrollView:
В Java
Ромэн Гай подробно объясняет это здесь: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
источник
Вы создаете пользовательский ListView, который не прокручивается
В вашем файле ресурсов макета
В файле Java
Создайте объект вашего customListview вместо ListView, например: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);
источник
Мы не могли использовать две прокрутки одновременно. У нас будет общая длина ListView и развернутый просмотр списка с общей высотой. Затем мы можем добавить ListView в ScrollView напрямую или с помощью LinearLayout, потому что у ScrollView непосредственно один дочерний элемент. скопируйте метод setListViewHeightBasedOnChildren (lv) в свой код и разверните просмотр списка, после чего вы можете использовать просмотр списка внутри scrollview. \ layout xml file
Метод onCreate в классе Activity:
источник
Это комбинация ответов Дуга, Гая Грега и Пола. Я обнаружил, что все это было необходимо при попытке использовать это с настраиваемым адаптером списка и нестандартными элементами списка, в противном случае просмотр списка приводил к сбою приложения (также происходил сбой при ответе Nex):
источник
Вы не должны ставить ListView в ScrollView потому ListView уже есть ScrollView. Так что это все равно что поместить ScrollView в ScrollView.
Что вы пытаетесь достичь?
источник
Я преобразовал @ DougW's
Utility
в C # (используется в Xamarin). Следующее работает отлично для элементов с фиксированной высотой в списке и будет в основном хорошо или, по крайней мере, хорошим началом, если только некоторые из элементов будут немного больше, чем стандартный элемент.Спасибо @DougW, это вывело меня из трудного положения, когда мне пришлось работать с кодом OtherPeople. :-)
источник
setListViewHeightBasedOnChildren()
метод? Потому что это не всегда работает для меня.Это единственное, что сработало для меня:
на Lollipop и далее вы можете использовать
Это включает или отключает вложенную прокрутку для этого представления, если вам нужна обратная совместимость со старой версией ОС, вам придется использовать RecyclerView.
источник
Раньше это было невозможно. Но с выпуском новых библиотек Appcompat и библиотек дизайна, это может быть достигнуто.
Вам просто нужно использовать NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html
Я не знаю, будет ли он работать с Listview или нет, но работает с RecyclerView.
Фрагмент кода:
источник
эй, у меня была похожая проблема. Я хотел отобразить представление списка, которое не прокручивалось, и я обнаружил, что манипулирование параметрами работало, но было неэффективно и могло бы вести себя по-разному на разных устройствах ... в результате это часть моего кода расписания, которая на самом деле делает это очень эффективно ,
Примечание: если вы используете это,
notifyDataSetChanged();
не будет работать так, как задумано, так как представления не будут перерисованы. Сделайте это, если вам нужно обойтиисточник
Есть две проблемы при использовании ListView внутри ScrollView.
1 - ListView должен полностью расширяться до своих дочерних высот. этот ListView разрешить это:
Высота делителя должна быть 0, вместо этого используйте отступы в строках.
2. ListView использует сенсорные события, поэтому ScrollView нельзя прокручивать как обычно. Этот ScrollView решает эту проблему:
Это лучший способ сделать это!
источник
Решение, которое я использую, состоит в том, чтобы добавить весь Контент ScrollView (что должно быть выше и ниже listView) как headerView и footerView в ListView.
Таким образом, он работает так же, как и конвертирование возобновляется так, как должно быть.
источник
благодаря коду Vinay, вот мой код, когда вы не можете иметь просмотр списка внутри прокрутки, но вам нужно что-то подобное
lativeLayout остается внутри ScrollView, поэтому все становится прокручиваемым :)
источник
Вот небольшая модификация на @djunod «s ответ , что мне нужно , чтобы сделать его работу отлично:
источник
попробуйте это, это работает для меня, я забыл, где я нашел это, где-то в переполнении стека, я не здесь, чтобы объяснить, почему это не работает, но это ответ :).
РЕДАКТИРОВАТЬ!, Я наконец узнал, где я получил код. Вот ! : ListView внутри ScrollView не прокручивается на Android
источник
Хотя предложенные методы setListViewHeightBasedOnChildren () работают в большинстве случаев, в некоторых случаях, особенно с большим количеством элементов, я заметил, что последние элементы не отображаются. Поэтому я решил имитировать простую версию поведения ListView для повторного использования любого кода адаптера, вот альтернатива ListView:
источник
Все эти ответы неверны !!! Если вы пытаетесь поместить представление списка в представление прокрутки, вам следует пересмотреть свой дизайн. Вы пытаетесь поместить ScrollView в ScrollView. Вмешательство в список повредит производительности списка. Это было разработано, чтобы быть таким как Android.
Если вы действительно хотите, чтобы список находился в той же прокрутке, что и другие элементы, все, что вам нужно сделать, - это добавить другие элементы в верхнюю часть списка с помощью простого оператора switch в вашем адаптере:
Адаптер списка может обрабатывать все, поскольку он отображает только то, что видно.
источник
Вся эта проблема исчезла бы, если бы у LinearLayout был метод setAdapter, потому что тогда, когда вы сказали кому-то использовать его, альтернатива была бы тривиальной.
Если вы действительно хотите прокрутить ListView внутри другого прокручиваемого представления, это не поможет, но в противном случае это, по крайней мере, даст вам представление.
Вам нужно создать собственный адаптер, чтобы объединить весь контент, который вы хотите прокрутить, и установить для него адаптер ListView.
У меня нет примера кода под рукой, но если вы хотите что-то вроде.
Затем вам нужно создать адаптер, который представляет весь этот контент. ListView / Adapters достаточно умны, чтобы обрабатывать разные типы, но вам нужно написать адаптер самостоятельно.
API пользовательского интерфейса Android не настолько развит, как почти все остальное, поэтому он не обладает такими же тонкостями, как другие платформы. Кроме того, когда вы делаете что-то на Android, вы должны быть настроены на Android (Unix), где вы ожидаете, что для того, чтобы делать все, что вам, вероятно, придется собирать функциональность из меньших частей и написать кучу вашего собственного кода, чтобы получить его Работа.
источник
Когда мы помещаем
ListView
внутрь,ScrollView
возникают две проблемы. Один из нихScrollView
измеряет его дочерние элементы в режиме НЕУТОЧНЕННЫЙ, поэтомуListView
устанавливает собственную высоту для размещения только одного элемента (я не знаю почему), другой -ScrollView
перехватывает событие касания, поэтомуListView
не прокручивает.Но мы можем поместить
ListView
внутрьScrollView
с некоторым обходным путем. Этот пост , мной, объясняет обходной путь. С помощью этого обходного пути мы также можем сохранитьListView
функцию утилизации.источник
Вместо того чтобы помещать представление списка в Scrollview, поместите остальную часть содержимого между просмотром списка и открытием Scrollview в качестве отдельного представления и установите это представление в качестве заголовка представления списка. Таким образом, вы, в конце концов, в конечном итоге получите только представление списка, взяв на себя ответственность за прокрутку.
источник
Эта библиотека - самое простое и быстрое решение проблемы.
источник
Вот моя версия кода, который вычисляет общую высоту представления списка. Этот работает для меня:
источник