- ListView внутри ScrollView
- ListView внутри ScrollView
- Разница между ScrollView и ListView
- The Developer World Is Yours
- The best place for Magento & Android tips and tricks… and much more!
- Expandable Listview inside scrollview
- 44 thoughts on “ Expandable Listview inside scrollview ”
- Как я могу поместить ListView в ScrollView без его сворачивания?
- 27 ответов
ListView внутри ScrollView
В работе над проектом возникла необходимость отрисовать лейаут такого вида: сверху компактным блоком располагаются детали топика, а под ними – список комментариев к этому топику. Сначала оно было реализовано естественным образом: лейаут деталей топика, а под ним – список. Позже ТЗ поменялось, и получилось, что нужно заголовок скролить вместе со списком.
Первым побуждением было сделать то, что вынесено в заголовок: поместить ListView внутрь ScrollView. Получившаяся штука отображалась некорректно, что заставило меня зарыться поглубже в гугл.
Во многих местах в сети (например, тут: https://groups.google.com/forum/#!topic/android-beginners/LRpLgGOy2Pc или тут: http://stackoverflow.com/questions/1526831/android-scrollview-layout-problem) напрямую говорится о том, что так делать нельзя. Для реализации таких вещей у ListView предусмотрены штатные заголовки (headers).
Добавление заголовков производится вызовом метода класса ListView:
где View v можно создавать любым способом (или явным вызовом конструктора, или через inflater).
View hv = . ;
listView.addHeaderView(hv);
Заголовков у ListView может быть больше одного. С их количеством, кстати, связана ещё одна особенность: по умолчанию заголовки тоже кликабельны, как и обычные элементы списка, клик на них вызывает отработку лиснеров, заданных вызовами setOnItemClickListener и setOnItemLongClickListener, так что позиция кликнутого элемента, которая передаётся в лиснеры в параметре position, будет смещена на количество заголовков. Этот факт нужно обязательно учитывать в лиснерах при обработке. Для этого у ListView есть метод:
который возвращает количество заголовков списка. На значение, которое он возвращает, можно, например, уменьшить значение 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
>
>;
Существует ещё один метод для добавления заголовков, чуть более сложный:
Он предоставляет возможность сделать заголовок некликабельным: если в третий параметр передать 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):
Источник
ListView внутри ScrollView
Если вы разрабатываете под Андройд, то наверняка сталкивались с задачей заставить ListView растягиваться по высоте своего контента, например чтобы поместить его внутрь ScrollView вместе с другими элементами. На самом деле подобный подход не рекомендуется использовать, т.к. ListView создавался не для этого, но мы не ищем легких путей и иногда проще «тупо сделать вот так».
Первое решение которое приходит в голову: назначить высоту wrap_content для ListView. Это не работает. Можете даже не пробовать, максимум чего вы добьетесь это растяжения высоты на первый элемент списка.
После еще некоторых попыток заставить список тянуться по высоте начинается гугление. К сожалению, гугл не выдает конкретного ответа на вопрос, только наводки и предложения. Все сводится к тому, чтобы вручную измерять общую высоту элементов списка и назначать списку сумарную высоту. Если вы хорошо разбираетесь в Андройде, наверное, это не будет проблемой, а для таких как я предлагаю готовое решение, честно найденное на просторах StackOverflow:
Этот метод нужно вызвать на нашем ListView после заполнения всех элементов. Все проверено и работает в Android 4.0+ (API 14+). На более ранних версиях честно не проверял, но думаю проблем быть не должно.
Есть еще один мелкий момент, который возможно кому-то пригодится. Если у вас используются разделители списка (divider), то нужно заменить одну строчку на это:
Источник
Разница между ScrollView и ListView
Может ли кто-нибудь объяснить разницу между прокруткой и списком? Когда использовать какой? И какой из них эффективнее?
ScrollView используется для размещения разных или одинаковых дочерних представлений или макетов, и все можно прокручивать.
ListView используется для размещения одного и того же вида просмотра или макета как нескольких элементов. Все эти элементы также прокручиваются.
Просто ScrollView предназначен для однородной и гетерогенной коллекции. ListView предназначен только для однородной коллекции.
Они совершенно разные.
ScrollView – простой прокручиваемый контейнер, который вы можете использовать, чтобы прокручивать все, что вы вкладываете в него, что может быть списком элементов, а может и нет.
ListView специально разработан для хранения списков, где элементы обычно выглядят одинаково (или, по крайней мере, следуют шаблону, например заголовки разделов). ListView также предназначен для подключения к источнику данных определенного типа, SQLite, массиву, поставщику контента и т. Д. ListView может масштабироваться для обработки огромного количества элементов списка.
Если у вас есть данные, которые нужно показать в списке, используйте ListView. Если вам просто нужно прокручивать содержимое, то ScrollView достаточно вероятен.
ScrollView просто размещает свое содержимое в прокручиваемом контейнере, вы можете редактировать его содержимое только путем добавления к нему представлений.
ListView – это класс, который использует адаптер, который обрабатывает создание представлений для ваших объектов данных, вам нужно только отредактировать данные, а изменения макета выполняются автоматически адаптером.
ScrollView следует использовать, когда у вас есть экран (например: форма с несколькими полями), которые не помещаются в один экран на небольших устройствах, так как такое scrollview предлагает пользователю возможность прокрутки вниз.
ListView следует использовать при представлении наборов данных.
ListView поддерживается адаптером, который содержит DataSource. Это позволяет легко отображать данные в строках.
ScrollView позволяет размещать содержимое внутри него, а если содержимое превышает размер ScrollView, оно позволяет прокручивать пользователя.
Они оба используют свое использование, но это зависит от того, что вы пытаетесь сделать.
Поскольку изображение стоит тысяча слов, вот примеры идеальной жизни:
Listview похож на приложение Kijiji
Scrollview похож на приложение EBay
Кроме того, см. Scrollview, как рекламный щит или стену, где вы можете наложить на нее кучу разных вещей.
И listview больше похож на страницу результатов: результаты имеют одинаковую природу, поэтому они прекрасно вписываются в список. Как и список контактов : все они имеют одну и ту же структуру; Номер телефона, имя и т.д.
В ListView Вы можете легко управлять расположением элементов в xml, которые вы хотите отобразить в списке.
Вы должны указать адаптеру ho много элементов, которые вы хотите в своем списке отображения.
Вы можете проектировать как для однородных, так и для разнородных представлений в зависимости от ваших требований, используя метод getItemViewType () адаптера.
Элементы ListView в списке создаются в соответствии с размером экрана. Т.е. количество элементов, которые могут отображаться на экране, создаются при просмотре списков во время выполнения, создаются дополнительные представления (элементы). Представления, которые отображаются один раз, кэшируются, когда они выходят из экрана, и когда список прокручивается обратно в предыдущее состояние, отображаются одни и те же представления, но это временное представление не создается, а они извлекаются из кеша.
Концепция кэша неприменима для ScrollView.
Все представления создаются сразу, когда они выходят на экран и не кэшируются, когда они перемещаются из экрана во время прокрутки. Они присутствуют в памяти (основной), что может привести к утечке памяти, поскольку количество созданных объектов не уничтожается сборщиком мусора, поскольку они ссылаются до тех пор, пока вы не находитесь на одной странице.
Хотя вы можете создавать как гомогенные, так и гетерогенные виды. Если в вашем списке больше элементов, которые будут отображаться в вашем списке, было бы утомительно управлять компоновкой независимо от того, работаете ли вы в xml или динамически создаете код Java.
Предпочтительно использовать scrollview, если у вас есть одна страница, которая не содержит список элементов, например, регистрационную форму, форму резервирования, но этот вид больше размера экрана, а затем поместите ScrollView в качестве родительского представления, также помните, что ScrollView может иметь только один Прямой макет / представление ребенка.
Источник
The Developer World Is Yours
The best place for Magento & Android tips and tricks… and much more!
Expandable Listview inside scrollview
When we have a ListView expandable inside ScrollView, we must make this in our layout, always expandable listview must be the last view in our layout:
In your onCreate
You need this function:
44 thoughts on “ Expandable Listview inside scrollview ”
This solution worked , thanks .
Well done 🙂
it worked for me thanks saved my day. 🙂
Hello
it is working for me but i tried to understand the content of the function setListViewHeight but i didn’t understand it
please if u have time to explain what u are doing in it i will be very happy
thank u in advance
Hi. of course.
I hope that my explanation will help you
The first step, we create variable height and width.
for each group we add group’s height.
if group is expandable, for each item we add item’s height.
LayoutParams are used by views to tell their parents how they want to be laid out. See ViewGroup Layout Attributes for a list of all child view attributes that this class supports.
Then we add divider height * number of group and we get total height in List.
getDividerHeight ()
Returns the height of the divider that will be drawn between each item in the list.
Now we check the minimum.
we add height to params
the last line we use
requestLayout()
Call this when something has changed which has invalidated the layout of this view.
Try to Make it in c# xamarin it will be great help for me.
Thanks for the code. It works great once the group item is clicked but it only shows one group item initially. Any help is appreciated!
It works fine for me .
But I have a problem in my case I don’t want to re-create activity on orientation change so I restrict it through manifest file so resolution specification I calculated in portrait mode reflected in landscape also , that’s why when I rotate my device it shows extra space in after last child .
Thanks in advance 🙂
A lot of thanks. Its working perfectly. Really nice .
Thanks again.
If you want to set height of exp. listview, when activity will start, you can use this function:
setListViewHeightForGroups(your_expList_AfterAcceptingAdapter);
This is not worked for me. please help me
This code should work. Which is your error?
NO error. calculating wrong height. For E.g If Actual height is 2378 but it’s 3500
But i click on expand it is working fine.
Worked!! Great work.
Is this condition right?
if (((listView.isGroupExpanded(i)) && (i != group))
|| ((!listView.isGroupExpanded(i)) && (i == group))) <
Seems like its never satisfies the condition.
oh, i got it, i was using in groupexpand and not on groupclick. i changed the condition, so its working on groupexpand
Thank you so much.
Thank you for this nice solution !
I just have an issue, I set android:dividerHeight=”5dp” in my ExpandableListView but when doing that I only see the first item.
What did I miss ?
Maybe because Android can´t calculate height when you set dividerHeight. Android is not perfect.
Thanks! It works (almost).
However , it only works after you click on a group item.
What about when you just open the layout and haven’t opened any group item?
Источник
Как я могу поместить ListView в ScrollView без его сворачивания?
Я искал решения этой проблемы, и единственный ответ, который я могу найти, кажется,»не помещайте ListView в ScrollView». Я до сих пор не вижу никакого реального объяснения почему хотя. Единственная причина, по которой я могу найти, заключается в том, что Google не думает, что вы должны хотеть этого. А я знаю, так и было.
Итак, вопрос в том, как вы можете поместить ListView в ScrollView без его сворачивания на минимальную высоту?
27 ответов
С помощью ListView сделать это не свиток, это очень дорого и идет против цели ListView . Вы должны не сделать это. Просто используйте LinearLayout вместо.
вот мое решение. Я довольно новичок в платформе Android, и я уверен, что это немного хакерский, особенно в части о вызове .измерьте непосредственно и установите LayoutParams.height свойство напрямую, но оно работает.
все, что вам нужно сделать, это позвонить Utility.setListViewHeightBasedOnChildren(yourListView) и он будет изменен, чтобы точно соответствовать высоте его элементов.
Это, безусловно, работать.
Вы должны просто заменить в xml-файле макета с этим Custom ScrollView как
Insted положить ListView внутри ScrollView , мы можем использовать ListView Как ScrollView . Вещи, которые должны быть в ListView можно поместить внутрь ListView . Другие макеты сверху и снизу ListView можно поместить, добавив макеты в верхний и Нижний колонтитулы ListView . Так вся ListView даст вам опыт скроллинга .
здесь много ситуаций, когда имеет смысл иметь ListView в ScrollView.
вот код, основанный на предложении DougW. работает во фрагменте, занимает меньше памяти.
звонок setListViewHeightBasedOnChildren(элемент управления ListView) на каждый внедренный элемент управления ListView.
ListView фактически уже способен измерять себя, чтобы быть достаточно высоким, чтобы отображать все элементы, но он не делает этого, когда вы просто указываете wrap_content (MeasureSpec.НЕОПРЕДЕЛЕННЫЙ.) Он будет делать это, когда задана высота с MeasureSpec.AT_MOST. С этими знаниями Вы можете создать очень простой подкласс для решения этой проблемы, который работает намного лучше, чем любое из решений, опубликованных выше. Вы все равно должны использовать wrap_content с этим подклассом.
манипулирования heightMeasureSpec должен быть AT_MOST с очень большим размером (целое число.MAX_VALUE >> 4) заставляет ListView измерять все его дочерние элементы до заданной (очень большой) высоты и устанавливать ее высоту соответственно.
это работает лучше, чем другие решения по нескольким причинам:
- он измеряет все правильно (отступы, разделители)
- он измеряет ListView во время прохождения меры
- должный к #2, оно регулирует изменения в ширине или количестве деталей правильно без дополнительного кода
С другой стороны, вы можете утверждать, что это зависит от недокументированного поведения в SDK, которое может измениться. С другой стороны, вы можете утверждать, что именно так wrap_content должен действительно работать с ListView и что текущее поведение wrap_content просто нарушено.
Если вы беспокоитесь, что поведение может измениться в будущем, вы должны просто скопировать функцию onMeasure и связанные с ней функции из элемент управления ListView.java и в свой собственный подкласс, затем сделайте путь AT_MOST через onMeasure для неопределенного также.
кстати, я считаю, что это вполне допустимый подход, когда вы работаете с небольшим количеством элементов списка. Это может быть неэффективно по сравнению с LinearLayout, но когда количество элементов невелико, использование LinearLayout является ненужной оптимизацией и, следовательно, ненужной сложностью.
для него есть встроенная настройка. На ScrollView:
Источник