Android: listview en listview

Estoy intentando colocar un listview dentro de un listviewitem. El listview interno no debe ser desplazable pero tomar todo el tamaño que necesita para mostrar todas sus filas. Hay una mejor manera de hacerlo? Mesa, rejilla, …? El problema que estoy enfrentando ahora es que el listview interior no toma el espacio que necesita, por lo que se corta en el final de la primera listitem. Si trato de desplazarse, sólo el listview exterior es el desplazamiento que es exactamente lo que quiero.

Como debes mirar Gracias, mi solución final es

LinearLayout layout = (LinearLayout) row.findViewById(R.id.LLBroadcasts); layout.removeAllViews(); for (Item b : bs.getItems()) { View child = _inflater.inflate(R.layout.item_row, null); TextView tvTitle = (TextView) child.findViewById(R.id.TVItemTitle); tvTitle.setText(b.getTitle()); TextView tvDesc = (TextView) child.findViewById(R.id.TVItemDescription); tvDesc.setText(b.getDescription()); layout.addView(child); } 

De la documentación de Android – ListView : ListView es un grupo de vistas que muestra una lista de elementos desplazables

En realidad, no desea desplazarse por esa vista de lista interna, desea desplazarse por la lista externa. Sin embargo, supongo que la lista interna puede variar en la cantidad de elementos que contiene.

En lugar de la vista interna de la lista, podría

  • Lineal , vea este tutorial o consulte Agregando contenido a un diseño lineal dinámicamente?
  • Tabla , vea este tutorial

Para el diseño lineal (código de ejemplo):

 // access your linear layout LinearLayout layout = (LinearLayout)findViewById(R.id.layout); // load the xml structure of your row View child = getLayoutInflater().inflate(R.layout.row); // now fill the row as you would do with listview //eg (TextView) child.findViewById(... ... // and than add it layout.addView(child); 

Debe guardar el diseño lineal en un soporte de visualización (consulte el patrón del titular de la vista ). Creo que el removeAllViews() sólo es necesario cuando la fila actual tiene menos filas internas que el reutilizado, por lo que también guardaría el número de filas en el titular de la vista.

Si el número máximo de filas internas no es alto, también podría pensar en ponerlas en caché en el titular de la vista para evitar el inflado y findByViewId (digamos en un ArrayList).

Tengo el mismo problema en mi App pero necesitaba usar una causa de ListView era un artículo compartido y no quise reproducir los componentes iguales. Así que .. Me acaba de arreglar el tamaño de ListView interna para mostrar programaticamente todas las filas y .. voila! Problema resuelto:

 ViewGroup.LayoutParams layoutParams = innerListView.getLayoutParams(); layoutParams.height = (int) context.getResources().getDimension(R.dimen.rowheight) * innerListView.getCount(); innerListView.setLayoutParams(layoutParams); CustomAdapter adapter = new CustomAdapter(context, blabla..); innerListView.setAdapter(adapter); rowListView.invalidate(); 

Tal vez alguien encontrará mi solución útil. Se basa en la respuesta @ChrLipp y utiliza LinearLayout.

 public class NotScrollableListView extends LinearLayout { private ListAdapter adapter; private DataChangeObserver dataChangeObserver; private Drawable divider; private int dividerHeight; private List<View> reusableViews = new ArrayList<>(); public NotScrollableListView(Context context) { super(context); } public NotScrollableListView(Context context, AttributeSet attrs) { super(context, attrs); setAttributes(attrs); } public NotScrollableListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setAttributes(attrs); } public ListAdapter getAdapter() { return adapter; } public void setAdapter(ListAdapter adapter) { if (this.adapter != null && dataChangeObserver != null) { this.adapter.unregisterDataSetObserver(dataChangeObserver); } this.adapter = adapter; } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (adapter != null) { dataChangeObserver = new DataChangeObserver(); adapter.registerDataSetObserver(dataChangeObserver); fillContents(); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (adapter != null) { adapter.unregisterDataSetObserver(dataChangeObserver); dataChangeObserver = null; } } private void fillContents() { // clearing contents this.removeAllViews(); final int count = adapter.getCount(); // item count final int reusableCount = reusableViews.size(); // count of cached reusable views // calculating of divider properties ViewGroup.LayoutParams dividerLayoutParams = null; if (divider != null && dividerHeight > 0) { dividerLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dividerHeight); } // adding items for (int i = 0; i < count; i++) { // adding item View converView = null; if (i < reusableCount) { // we have cached view converView = reusableViews.get(i); } View view = adapter.getView(i, converView, this); if (i >= reusableCount) { // caching view reusableViews.add(view); } addView(view); // adding divider if (divider != null && dividerHeight > 0) { if (i < count - 1) { ImageView dividerView = new ImageView(getContext()); dividerView.setImageDrawable(divider); dividerView.setLayoutParams(dividerLayoutParams); addView(dividerView); } } } } private void setAttributes(AttributeSet attributes) { int[] dividerAttrs = new int[]{android.R.attr.divider, android.R.attr.dividerHeight}; TypedArray a = getContext().obtainStyledAttributes(attributes, dividerAttrs); try { divider = a.getDrawable(0); dividerHeight = a.getDimensionPixelSize(1, 0); } finally { a.recycle(); } setOrientation(VERTICAL); } private class DataChangeObserver extends DataSetObserver { @Override public void onChanged() { super.onChanged(); fillContents(); } @Override public void onInvalidated() { super.onInvalidated(); fillContents(); } } } <com.sample.ui.view.NotScrollableListView android:id="@+id/internalList" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@color/list_divider_color" android:dividerHeight="@dimen/list_divider_width" /> 

@ Pruebe esta clase anidada

Esto funciona para listView inside listView O 2 listview s en la misma activity

  <com.example.taskgrptaskslistview.NestedListView android:id="@+id/listviewTasks" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_marginBottom="2dp" android:layout_weight="1" android:cacheColorHint="#00000000" > </com.example.taskgrptaskslistview.NestedListView> </LinearLayout> 

NestedListView:

 import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListAdapter; import android.widget.ListView; public class NestedListView extends ListView implements OnTouchListener, OnScrollListener { private int listViewTouchAction; private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99; public NestedListView(Context context, AttributeSet attrs) { super(context, attrs); listViewTouchAction = -1; setOnScrollListener(this); setOnTouchListener(this); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { if (listViewTouchAction == MotionEvent.ACTION_MOVE) { scrollBy(0, -1); } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int newHeight = 0; final int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (heightMode != MeasureSpec.EXACTLY) { ListAdapter listAdapter = getAdapter(); if (listAdapter != null && !listAdapter.isEmpty()) { int listPosition = 0; for (listPosition = 0; listPosition < listAdapter.getCount() && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) { View listItem = listAdapter.getView(listPosition, null, this); //now it will not throw a NPE if listItem is a ViewGroup instance if (listItem instanceof ViewGroup) { listItem.setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } listItem.measure(widthMeasureSpec, heightMeasureSpec); newHeight += listItem.getMeasuredHeight(); } newHeight += getDividerHeight() * listPosition; } if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) { if (newHeight > heightSize) { newHeight = heightSize; } } } else { newHeight = getMeasuredHeight(); } setMeasuredDimension(getMeasuredWidth(), newHeight); } @Override public boolean onTouch(View v, MotionEvent event) { if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { if (listViewTouchAction == MotionEvent.ACTION_MOVE) { scrollBy(0, 1); } } return false; } } 

He intentado hacer esta estructura exacta (un ListView dentro de un ListView ) y tenía el mismo problema de que sólo muestra el primer elemento de la ListView interior. Lo arreglé cambiando el layout_height de la lista interna de match_parent a un conjunto dp .

Parecía que funcionaba exactamente como yo quería.

  • Android: listview item width fill_parent no funciona
  • ListFragment Elemento de fondo seleccionado
  • Columnas en ListView Android
  • android usando setlistadapter () sin extender listactivity
  • Android ListView en Actividad que se refresca en el cambio de orientación
  • Visualización de filas vacías en Android listview
  • ListView onclick va a una nueva actividad
  • ListSelector en ListView no funciona
  • Android ListView - pequeña línea entre los elementos
  • La lista muestra el color negro
  • Error con mi lista, ScrollView y botones
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.