Intereting Posts
Поддерживается ли Android POSIX? Android Camera Intent Сохранение ландшафта изображения при съемке Android: вызов нестатических методов из статического класса Handler ListView покажет пустое сообщение до загрузки данных Существуют ли альтернативы использованию Google-биллинга в приложении, чтобы избежать публикации частной информации? Могу ли я обнаружить наличие / отсутствие «светодиодного уведомления» на устройстве Android? Сброс и база данных SQLite на Android Аутентификация пользователя, входящего в систему с FB на моем сервере, с помощью диспетчера учетных записей Android Средство просмотра иерархии не вычисляет Measure, Layout, Draw и показывает недоступно Android – отображает постоянное представление обо всех действиях TextView: заставить его усекать без уважения к пробелам между словами Android: обновление виджета при доступности сетевого подключения Android-анимация для Android Как программно определить, какой формат XML используют мои приложения для Android? Дамп мобильной памяти

Как я могу поместить ListView в ScrollView без его свертывания?

Я искал для решения этой проблемы, и единственный ответ, который я могу найти, кажется, « не помещайте ListView в ScrollView ». Я пока не вижу никаких реальных объяснений, почему . Единственная причина, по которой я могу найти, – это то, что Google не думает, что вам следует это делать. Ну, я так и сделал.

Итак, вопрос в том, как вы можете разместить ListView в ScrollView без его свертывания до минимальной высоты?

Solutions Collecting From Web of "Как я могу поместить ListView в ScrollView без его свертывания?"

Использование ListView чтобы сделать его не прокруткой, чрезвычайно дорого и противоречит всей цели ListView . Вы НЕ должны этого делать. Просто используйте LinearLayout .

Вот мое решение. Я довольно новичок в платформе Android, и я уверен, что это немного хакерское, особенно в части о вызове .measure напрямую и настройке свойства LayoutParams.height , но оно работает.

Все, что вам нужно сделать, это вызвать Utility.setListViewHeightBasedOnChildren(yourListView) и он будет изменен в соответствии с высотой его элементов.

 public class Utility { public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition return; } int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom(); for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); if (listItem instanceof ViewGroup) { listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); } } 

Это определенно будет работать …………
Вы должны просто заменить свой <ScrollView ></ScrollView> в XML-файл макета таким Custom ScrollView как <com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >

 package com.tmd.utils; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.ScrollView; public class VerticalScrollview extends ScrollView{ public VerticalScrollview(Context context) { super(context); } public VerticalScrollview(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" ); super.onTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: return false; // redirect MotionEvents to ourself case MotionEvent.ACTION_CANCEL: Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" ); super.onTouchEvent(ev); break; case MotionEvent.ACTION_UP: Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" ); return false; default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break; } return false; } @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() ); return true; } } 

При запуске ListView внутри ScrollView мы можем использовать ListView в качестве ScrollView . Вещи, которые должны быть в ListView могут быть помещены в ListView . Другие макеты сверху и снизу ListView можно поместить, добавив макеты в верхний и нижний колонтитулы ListView . Таким образом, весь ListView даст вам опыт прокрутки.

Существует множество ситуаций, когда имеет смысл иметь ListView в ScrollView.

Вот код, основанный на предложении DougW … работает в фрагменте, занимает меньше памяти.

 public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST); int totalHeight = 0; View view = null; for (int i = 0; i < listAdapter.getCount(); i++) { view = listAdapter.getView(i, view, listView); if (i == 0) { view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT)); } view.measure(desiredWidth, MeasureSpec.UNSPECIFIED); totalHeight += view.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); listView.requestLayout(); } 

Вызовите setListViewHeightBasedOnChildren (listview) для каждого встроенного списка.

Для этого есть встроенная настройка. В ScrollView:

 android:fillViewport="true" 

В Java,

 mScrollView.setFillViewport(true); 

Ромен Гай объясняет это подробно: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

ListView на самом деле уже способен измерить себя как достаточно высокий, чтобы отображать все элементы, но он не делает этого, когда вы просто указываете wrap_content (MeasureSpec.UNSPECIFIED). Он будет делать это при заданной высоте с помощью MeasureSpec.AT_MOST. С помощью этих знаний вы можете создать очень простой подкласс для решения этой проблемы, который работает намного лучше, чем любое из вышеперечисленных решений. Вы должны по-прежнему использовать wrap_content с этим подклассом.

 public class ListViewForEmbeddingInScrollView extends ListView { public ListViewForEmbeddingInScrollView(Context context) { super(context); } public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 4, MeasureSpec.AT_MOST)); } } 

Манипулирование heightMeasureSpec как AT_MOST с очень большим размером (Integer.MAX_VALUE >> 4) заставляет ListView измерять все его дочерние элементы до данной (очень большой) высоты и соответственно устанавливать ее высоту.

Это работает лучше, чем другие решения по нескольким причинам:

  1. Он правильно измеряет все (отступы, разделители)
  2. Он измеряет ListView во время прохождения меры
  3. Из-за # 2 он обрабатывает изменения по ширине или количеству элементов правильно без какого-либо дополнительного кода

С другой стороны, вы можете утверждать, что это связано с недокументированным поведением в SDK, которое может измениться. С другой стороны, вы можете утверждать, что именно так должно работать wrap_content с ListView и что текущее поведение wrap_content просто сломано.

Если вы опасаетесь, что поведение может измениться в будущем, вы должны просто скопировать функцию onMeasure и связанные с ней функции из списка ListView.java и в свой собственный подкласс, а затем сделать путь AT_MOST с помощью функции onMeasure для UNSPECIFIED.

Кстати, я считаю, что это очень эффективный подход, когда вы работаете с небольшим количеством элементов списка. Он может быть неэффективен по сравнению с LinearLayout, но когда количество элементов невелико, использование LinearLayout является ненужной оптимизацией и, следовательно, ненужной сложностью.

Мы не могли бы использовать две прокрутки одновременно. Мы получим общую длину ListView и раскройте listview с общей высотой. Затем мы можем добавить ListView в ScrollView напрямую или с помощью LinearLayout, потому что ScrollView имеет прямо один ребенок. Скопируйте метод setListViewHeightBasedOnChildren (lv) в свой код и разверните listview, после чего вы можете использовать listview внутри scrollview. \ Layout xml-файл

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#1D1D1D" android:orientation="vertical" android:scrollbars="none" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#1D1D1D" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="40dip" android:background="#333" android:gravity="center_vertical" android:paddingLeft="8dip" android:text="First ListView" android:textColor="#C7C7C7" android:textSize="20sp" /> <ListView android:id="@+id/first_listview" android:layout_width="260dp" android:layout_height="wrap_content" android:divider="#00000000" android:listSelector="#ff0000" android:scrollbars="none" /> <TextView android:layout_width="fill_parent" android:layout_height="40dip" android:background="#333" android:gravity="center_vertical" android:paddingLeft="8dip" android:text="Second ListView" android:textColor="#C7C7C7" android:textSize="20sp" /> <ListView android:id="@+id/secondList" android:layout_width="260dp" android:layout_height="wrap_content" android:divider="#00000000" android:listSelector="#ffcc00" android:scrollbars="none" /> </LinearLayout> </ScrollView> </LinearLayout> 

OnCreate метод в классе активности:

  import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview_inside_scrollview); ListView list_first=(ListView) findViewById(R.id.first_listview); ListView list_second=(ListView) findViewById(R.id.secondList); ArrayList<String> list=new ArrayList<String>(); for(int x=0;x<30;x++) { list.add("Item "+x); } ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,list); list_first.setAdapter(adapter); setListViewHeightBasedOnChildren(list_first); list_second.setAdapter(adapter); setListViewHeightBasedOnChildren(list_second); } public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); } 

Это комбинация ответов Дуга, Доброго Гая Грега и Павла. Я обнаружил, что это было необходимо при попытке использовать это с помощью настраиваемого адаптера listview и нестандартных элементов списка, иначе listview разбил приложение (также разбился с ответом Nex):

 public void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom(); for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); if (listItem instanceof ViewGroup) listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); } 

Вы не должны помещать ListView в ScrollView, потому что ListView уже является ScrollView. Таким образом, это будет похоже на создание ScrollView в ScrollView.

Что вы пытаетесь достичь?

Эй, у меня была аналогичная проблема. Я хотел отобразить представление списка, которое не прокручивалось, и я обнаружил, что манипуляция параметрами работает, но неэффективна и будет вести себя по-разному на разных устройствах. В результате это часть моего кода расписания, которая на самом деле делает это очень эффективно ,

 db = new dbhelper(this); cursor = db.dbCursor(); int count = cursor.getCount(); if (count > 0) { LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layoutId); startManagingCursor(YOUR_CURSOR); YOUR_ADAPTER(**or SimpleCursorAdapter **) adapter = new YOUR_ADAPTER(this, R.layout.itemLayout, cursor, arrayOrWhatever, R.id.textViewId, this.getApplication()); int i; for (i = 0; i < count; i++){ View listItem = adapter.getView(i,null,null); linearLayout.addView(listItem); } } 

Примечание: если вы используете это, notifyDataSetChanged(); Не будет работать так, как предполагалось, поскольку представления не будут перерисовываться. Сделайте это, если вам нужна работа

 adapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { super.onChanged(); removeAndRedrawViews(); } }); 

Есть две проблемы при использовании ListView внутри ScrollView.

1- ListView должен полностью расширяться до высоты своих детей. Этот ListView разрешает это:

 public class ListViewExpanded extends ListView { public ListViewExpanded(Context context, AttributeSet attrs) { super(context, attrs); setDividerHeight(0); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST)); } } 

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

2- ListView потребляет события касания, поэтому ScrollView нельзя прокручивать, как обычно. Этот ScrollView решает эту проблему:

 public class ScrollViewInterceptor extends ScrollView { float startY; public ScrollViewInterceptor(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { onTouchEvent(e); if (e.getAction() == MotionEvent.ACTION_DOWN) startY = e.getY(); return (e.getAction() == MotionEvent.ACTION_MOVE) && (Math.abs(startY - e.getY()) > 50); } } 

Это лучший способ найти трюк!

Я преобразовал утилиту @ DougW в C # (используется в Xamarin). Следующее работает отлично для элементов фиксированной высоты в списке и будет в основном прекрасным или, по крайней мере, хорошим началом, если только некоторые из элементов немного больше, чем стандартный элемент.

 // You will need to put this Utility class into a code file including various // libraries, I found that I needed at least System, Linq, Android.Views and // Android.Widget. using System; using System.Linq; using Android.Views; using Android.Widget; namespace UtilityNamespace // whatever you like, obviously! { public class Utility { public static void setListViewHeightBasedOnChildren (ListView listView) { if (listView.Adapter == null) { // pre-condition return; } int totalHeight = listView.PaddingTop + listView.PaddingBottom; for (int i = 0; i < listView.Count; i++) { View listItem = listView.Adapter.GetView (i, null, listView); if (listItem.GetType () == typeof(ViewGroup)) { listItem.LayoutParameters = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent); } listItem.Measure (0, 0); totalHeight += listItem.MeasuredHeight; } listView.LayoutParameters.Height = totalHeight + (listView.DividerHeight * (listView.Count - 1)); } } } 

Благодаря @DougW, это привело меня в затруднительное положение, когда мне пришлось работать с OtherPeople'Code. 🙂

Благодаря коду Вина здесь мой код, когда у вас нет списка в прокрутке, но вам нужно что-то подобное

 LayoutInflater li = LayoutInflater.from(this); RelativeLayout parent = (RelativeLayout) this.findViewById(R.id.relativeLayoutCliente); int recent = 0; for(Contatto contatto : contatti) { View inflated_layout = li.inflate(R.layout.header_listview_contatti, layout, false); inflated_layout.setId(contatto.getId()); ((TextView)inflated_layout.findViewById(R.id.textViewDescrizione)).setText(contatto.getDescrizione()); ((TextView)inflated_layout.findViewById(R.id.textViewIndirizzo)).setText(contatto.getIndirizzo()); ((TextView)inflated_layout.findViewById(R.id.textViewTelefono)).setText(contatto.getTelefono()); ((TextView)inflated_layout.findViewById(R.id.textViewMobile)).setText(contatto.getMobile()); ((TextView)inflated_layout.findViewById(R.id.textViewFax)).setText(contatto.getFax()); ((TextView)inflated_layout.findViewById(R.id.textViewEmail)).setText(contatto.getEmail()); RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); if (recent == 0) { relativeParams.addRule(RelativeLayout.BELOW, R.id.headerListViewContatti); } else { relativeParams.addRule(RelativeLayout.BELOW, recent); } recent = inflated_layout.getId(); inflated_layout.setLayoutParams(relativeParams); //inflated_layout.setLayoutParams( new RelativeLayout.LayoutParams(source)); parent.addView(inflated_layout); } 

RelativeLayout остается внутри ScrollView, поэтому все становится прокручиваемым 🙂

Вот небольшая модификация ответа @djunod , что мне нужно, чтобы он работал отлично:

 public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if(listAdapter == null) return; if(listAdapter.getCount() <= 1) return; int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST); int totalHeight = 0; View view = null; for(int i = 0; i < listAdapter.getCount(); i++) { view = listAdapter.getView(i, view, listView); view.measure(desiredWidth, MeasureSpec.UNSPECIFIED); totalHeight += view.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); listView.requestLayout(); } 

Попробуйте это, это работает для меня, я забыл, где я его нашел, где-то в переполнении стека, я не здесь, чтобы объяснить это, почему это не работает, но это ответ :).

  final ListView AturIsiPulsaDataIsiPulsa = (ListView) findViewById(R.id.listAturIsiPulsaDataIsiPulsa); AturIsiPulsaDataIsiPulsa.setOnTouchListener(new ListView.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // Disallow ScrollView to intercept touch events. v.getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: // Allow ScrollView to intercept touch events. v.getParent().requestDisallowInterceptTouchEvent(false); break; } // Handle ListView touch events. v.onTouchEvent(event); return true; } }); AturIsiPulsaDataIsiPulsa.setClickable(true); AturIsiPulsaDataIsiPulsa.setAdapter(AturIsiPulsaDataIsiPulsaAdapter); 

EDIT!, Я наконец узнал, где я получил код. Вот ! : ListView внутри ScrollView не прокручивается на Android

Хотя предлагаемые методы setListViewHeightBasedOnChildren () работают в большинстве случаев, в некоторых случаях, особенно с большим количеством элементов, я заметил, что последние элементы не отображаются. Поэтому я решил подражать простой версии поведения ListView , чтобы повторно использовать любой код адаптера, вот альтернатива ListView:

 import android.content.Context; import android.database.DataSetObserver; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.ListAdapter; public class StretchedListView extends LinearLayout { private final DataSetObserver dataSetObserver; private ListAdapter adapter; private OnItemClickListener onItemClickListener; public StretchedListView(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(LinearLayout.VERTICAL); this.dataSetObserver = new DataSetObserver() { @Override public void onChanged() { syncDataFromAdapter(); super.onChanged(); } @Override public void onInvalidated() { syncDataFromAdapter(); super.onInvalidated(); } }; } public void setAdapter(ListAdapter adapter) { ensureDataSetObserverIsUnregistered(); this.adapter = adapter; if (this.adapter != null) { this.adapter.registerDataSetObserver(dataSetObserver); } syncDataFromAdapter(); } protected void ensureDataSetObserverIsUnregistered() { if (this.adapter != null) { this.adapter.unregisterDataSetObserver(dataSetObserver); } } public Object getItemAtPosition(int position) { return adapter != null ? adapter.getItem(position) : null; } public void setSelection(int i) { getChildAt(i).setSelected(true); } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } public ListAdapter getAdapter() { return adapter; } public int getCount() { return adapter != null ? adapter.getCount() : 0; } private void syncDataFromAdapter() { removeAllViews(); if (adapter != null) { int count = adapter.getCount(); for (int i = 0; i < count; i++) { View view = adapter.getView(i, null, this); boolean enabled = adapter.isEnabled(i); if (enabled) { final int position = i; final long id = adapter.getItemId(position); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(null, v, position, id); } } }); } addView(view); } } } } 

Решение, которое я использую, заключается в том, чтобы добавить все содержимое ScrollView (что должно быть выше и под listView) как headerView и footerView в ListView.

Таким образом, он работает так же, как конвертируется, как и должно быть.

Все эти ответы неверны !!! Если вы пытаетесь поместить список в прокрутку, вы должны пересмотреть свой дизайн. Вы пытаетесь поместить ScrollView в ScrollView. Вмешательство в список повредит производительности списка. Он был разработан для Android.

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

 class MyAdapter extends ArrayAdapter{ public MyAdapter(Context context, int resource, List objects) { super(context, resource, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewItem viewType = getItem(position); switch(viewType.type){ case TEXTVIEW: convertView = layouteInflater.inflate(R.layout.textView1, parent, false); break; case LISTITEM: convertView = layouteInflater.inflate(R.layout.listItem, parent, false); break; } return convertView; } } 

Адаптер списка может обрабатывать все, поскольку он отображает только то, что видно.

Вы создаете пользовательский ListView, который не прокручивается

 public class NonScrollListView extends ListView { public NonScrollListView(Context context) { super(context); } public NonScrollListView(Context context, AttributeSet attrs) { super(context, attrs); } public NonScrollListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom); ViewGroup.LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); } } 

В файле ресурсов макета

 <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- com.Example Changed with your Package name --> <com.Example.NonScrollListView android:id="@+id/lv_nonscroll_list" android:layout_width="match_parent" android:layout_height="wrap_content" > </com.Example.NonScrollListView> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/lv_nonscroll_list" > <!-- Your another layout in scroll view --> </RelativeLayout> </RelativeLayout> 

В файле Java

Создайте объект customListview вместо ListView, например: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);

Вся эта проблема просто исчезнет, ​​если у LinearLayout был метод setAdapter, потому что тогда, когда вы сказали кому-то использовать его, альтернатива была бы тривиальной.

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

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

У меня нет образца кода, но если вам нужно что-то вроде.

 <ListView/> (other content) <ListView/> 

Затем вам нужно создать адаптер, который представляет все это содержимое. ListView / Adapters достаточно умны, чтобы обрабатывать разные типы, но вам нужно написать адаптер самостоятельно.

API-интерфейс Android Android не настолько зрелый, как и все остальное, поэтому он не имеет таких же тонкостей, как другие платформы. Кроме того, когда вы делаете что-то на android, вам нужно быть в Android-симуляции (unix), где вы ожидаете, что что-то, что вам, вероятно, придется собирать для работы с меньшими частями, и написать кучу собственного кода, чтобы получить его Работа.

Когда мы размещаем ListView внутри ScrollView возникают две проблемы. Один из них – ScrollView измеряет его дочерние ScrollView в режиме ScrollView , поэтому ListView устанавливает собственную высоту для размещения только одного элемента (я не знаю почему), другой – ScrollView перехватывает событие касания, поэтому ListView не прокручивает.

Но мы можем разместить ListView внутри ScrollView с помощью некоторого обходного пути. Этот пост , я, объясняет обходное решение. К этому решению мы также можем сохранить функцию рециркуляции ListView .

Это единственное, что сработало для меня:

На Lollipop и далее вы можете использовать

 yourtListView.setNestedScrollingEnabled(true); 

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

Эта библиотека является самым простым и быстрым решением проблемы.

Вот моя версия кода, который вычисляет общую высоту списка. Это работает для меня:

  public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null || listAdapter.getCount() < 2) { // pre-condition return; } int totalHeight = 0; int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(BCTDApp.getDisplaySize().width, View.MeasureSpec.AT_MOST); int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); if (listItem instanceof ViewGroup) listItem.setLayoutParams(lp); listItem.measure(widthMeasureSpec, heightMeasureSpec); totalHeight += listItem.getMeasuredHeight(); } totalHeight += listView.getPaddingTop() + listView.getPaddingBottom(); totalHeight += (listView.getDividerHeight() * (listAdapter.getCount() - 1)); ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight; listView.setLayoutParams(params); listView.requestLayout(); } 

Instead of putting the listview inside Scrollview, put the rest of the content between listview and the opening of the Scrollview as a separate view and set that view as the header of the listview. So you will finally end up only list view taking charge of Scroll.