Intereting Posts
Что означают эти предупреждения Android logcat? Как настроить gradle-2.2.1-all.zip вручную Базы данных RDF на Android Должен ли внутренний класс DialogFragment статичным или нет? Robolectric выбрасывает ресурсы $ NotFoundException при попытке доступа к ресурсу в исходной папке Android SpeechRecognizer обнаруживает свой собственный звуковой сигнал как речь и выходы Прокси SSL / Чарльз и проблемы с Android Как определить, какой файл MP3 закончился в MediaPlayer.OnCompletionListener? Ошибка получения родительского элемента для элемента: ресурс не найден, который соответствует указанному имени после обновления до AppCompat v23 Можно разместить TextView внутри RadioGroup. Но, это хорошая практика? OnItemClickListener и OnClickListener не работают в ListView Учебник getRotationMatrix и getOrientation Сохранение предложения в Google Кошельке Как отправить данные POST с кодом в веб-обозревателе Android Как проверить программно, работает ли приложение в режиме отладки или нет?

Вычислите размер представления списка или как рассказать об этом полностью

В настоящее время я пытаюсь использовать ListView внутри ScrollView. Я знаю, из того, что я читал, это выглядит сверху вниз, но я пытаюсь полностью расширить ListView, показывая все его строки, поэтому нет необходимости прокручивать его. Однако я боролся с тем, как рассказать, что ListView полностью расширяется, чтобы показать все его строки, так как ему нужна определенная высота. Кто-нибудь знает способ расчета высоты полностью расширенного ListView до его рисования?

Эта проблема в основном связана с тем, что вы не можете поместить прокручиваемый вид внутри другого прокручиваемого представления. Я согласен с тем, что ListView не сможет прокручивать, пока я могу его расширить, чтобы показать все его строки. Однако я не могу этого сделать, не имея возможности дать ему определенную высоту, что, по-видимому, мне нужно будет вычислить.

Посмотрите URL-адрес ниже для эскиза (я новый пользователь, поэтому мне не разрешено публиковать его). Это показывает, что мой полный макет слишком велик для «физического» экрана и ему нужно прокрутить, чтобы показать остальную часть списка и кнопки внизу. Я пытаюсь понять, что «виртуальный» экран слишком велик, чтобы соответствовать одному экрану даже без ListView.

http://img51.imageshack.us/img51/7210/screenmockup.png

Solutions Collecting From Web of "Вычислите размер представления списка или как рассказать об этом полностью"

Ну, спасибо Руди, его предложения были очень полезными. Вот как это можно реализовать.

1) Создайте новый класс, который расширяет ListView:

package com.example.android.views; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.widget.ListView; public class ExpandedListView extends ListView { private android.view.ViewGroup.LayoutParams params; private int old_count = 0; public ExpandedListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { if (getCount() != old_count) { old_count = getCount(); params = getLayoutParams(); params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0); setLayoutParams(params); } super.onDraw(canvas); } } 

2) … и, наконец, добавьте новое представление в ваш файл макета xml:

 <com.example.android.views.ExpandedListView android:id="@+id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scrollbars="none" android:padding="0px" /> 

Правильный способ расчета высоты – это точно:

 int height = 0; for (int i = 0; i < listView.getChildCount(); i++) { height += listView.getChildAt(i).getMeasuredHeight(); height += listView.getDividerHeight(); } 

Внимание! Правильный способ расчета высоты не

 params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0); 

Мы должны добавить высоту каждой (минус одной) высоты разделителя.

 if(oldCount > 0 && getCount() > 0) params.height = getCount() * (getChildAt(0).getHeight() + getDividerHeight()) - getDividerHeight(); else params.height = 0; 

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

 @Override public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { if (this.isExpanded) { final int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); final ViewGroup.LayoutParams params = this.getLayoutParams(); params.height = this.getMeasuredHeight(); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } 

Нельзя размещать ListView в ScrollView. ListView уже прокручивается.

По умолчанию ListView должен полностью развернуться, если это единственное в макете.

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

 <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" orientation="vertical"> <TextView id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ListView id="@+id/listView" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> 

Редактировать: ListView действительно предназначен для прокрутки … макет экрана, который у вас есть на скриншоте, на самом деле не похож на «андроидный путь».

Однако, если вы действительно хотите обойти это, вы можете попробовать раздуть одну из строк, получить ее minHeight и умножить на количество элементов в адаптере ListView.

 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.label_value_row, null, false); int height = adapter.getCount() * view.getMinHeight(); 

Я взял функцию из ответа djunod (функция в статическом классе)

Рассчитать размер списка

И измените метод ondraw следующим образом. Он успешно работает после успешных операций удаления.

Вот мой последний класс

Class ExpandedListView расширяет ListView {

 private android.view.ViewGroup.LayoutParams params; private int old_count = 0; public ExpandedListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { if (getCount() != old_count) { params = getLayoutParams(); old_count = getCount(); int totalHeight = 0; for (int i = 0; i < getCount(); i++) { this.measure(0, 0); totalHeight += getMeasuredHeight(); } params = getLayoutParams(); params.height = totalHeight + (getDividerHeight() * (getCount() - 1)); setLayoutParams(params); } super.onDraw(canvas); } 

}

Теперь мой список расширяется после вставки строки без прокрутки. И после удаления строки этот код вычисляет правильный размер для listview. Я не знаю, как он работает. Но он работает. BR

Я изучал, как это сделать, и хотя на этот вопрос уже был дан ответ, я хотел бы предложить решение, которое, я думаю, будет лучше:

Посмотрев исходный код ListView, вы можете увидеть следующее внутри кода onMeasure (…):

 if (heightMode == MeasureSpec.AT_MOST) { // TODO: after first layout we should maybe start at the first visible position, not 0 heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1); } 

Поэтому просто вызовите меру listView и передайте MeasureSpec.AT_MOST для высоты вместо обычного MeasureSpec.UNSPECIFIED.

Я делаю следующее, чтобы измерить список и поместить его во всплывающее окно:

  int widthMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels, MeasureSpec.AT_MOST); mCatalogView.measure(widthMeasureSpec, heightMeasureSpec); mPopup.setWidth(mCatalogView.getMeasuredWidth()); mPopup.setHeight(mCatalogView.getMeasuredHeight()); 

Я закончил переопределять onDraw() ListView и вычислял среднюю высоту видимых строк в представлении, а затем оценивал фактическую высоту списка в зависимости от количества элементов в адаптере. Эта оценка выполняется несколько раз, пока все строки не будут видны.

Я знаю, что уже поздно, и есть уже и ответ, но если вы действительно хотите это сделать, это простой способ:

Создать представление списка Элемент с определенной высотой

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="horizontal" > <ImageView android:id="@+id/lvItemSurpriseMeImgRestaurant" android:layout_width="80dp" android:layout_height="80dp" android:layout_marginLeft="5dp" android:contentDescription="@string/restaurantImageDescriptionColon" /> </LinearLayout> 

Теперь мы знаем, что Item имеет 100dp , и если мы знаем количество предметов, то это очень просто

Установите высоту ListView буквально в значение NoOfItems * Height + 10dp extra

Это никогда не изменится, так как все объединяются в dp .

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

  <ListView android:id="@+id/menuListView" android:layout_width="match_parent" android:layout_height="210dp" android:layout_weight="1.0" tools:ignore="NestedScrolling" tools:listitem="@layout/menu_item" > </ListView> 

Если у вас есть предметы с разной высотой, вам нужно использовать этот метод:

 public void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter != null) { int numberOfItems = listAdapter.getCount(); // Get total height of all items. int totalItemsHeight = 0; for (int itemPos = 0; itemPos < numberOfItems; itemPos++) { View item = listAdapter.getView(itemPos, null, listView); float px = 300 * (listView.getResources().getDisplayMetrics().density); item.measure( View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); int height = item.getMeasuredHeight(); totalItemsHeight += height; } // Get total height of all item dividers. int totalDividersHeight = listView.getDividerHeight() * (numberOfItems - 1); // Set list height. ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalItemsHeight + totalDividersHeight; listView.setLayoutParams(params); listView.requestLayout(); } } 

Он отлично работает с любым ListView с любыми элементами

Использование этого будет сработано:

 public class ListViewEx extends ListView { public ListViewEx(Context context) { super(context); } /** * @param context * @param attrs */ public ListViewEx(Context context, AttributeSet attrs) { super(context, attrs); } /** * 设置不滚动*/ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { return ev.getAction()==MotionEvent.ACTION_MOVE||super.dispatchTouchEvent(ev); } 

}