Agregar margen por encima del elemento ListView superior (y por debajo del último) en Android


Esta es una pregunta bastante buena sobre el diseño de los elementos en una vista de lista en Android.

Tengo una actividad con una barra de título en la parte superior y una vista de lista que ocupa el resto de la pantalla. Quiero que mi ListView aparezca con relleno de 10dp a la izquierda, derecha y arriba, pero cuando desplaces la ListView hacia arriba, quiero que cubra el relleno de 10dp superior antes de desaparecer bajo el borde desvanecido. Del mismo modo, cuando se desplaza a la parte inferior, el último elemento de la lista debe aparecer con 10dp entre la parte inferior del último elemento de la lista y la parte inferior real de la pantalla (si te estás preguntando por qué, es porque hay una bonita imagen de fondo que quiero asomar alrededor de la vista de la lista).

He intentado agregar relleno a la propia ListView, pero luego cuando se desplaza la lista desaparece bajo el borde del relleno.

Soy de un entorno web dev, y la analogía sería agregar margen por encima del primer elemento de la lista (y por debajo del último elemento de la lista).

Author: Mick Byrne, 2011-06-09

5 answers

Usted escribió:

He intentado agregar relleno a la propia ListView, pero luego cuando se desplaza la lista desaparece bajo el borde del relleno.

Conjunto ListView's clipToPadding atributo false. Esto permitirá el relleno alrededor de la ListView y desplazándose hasta el final del diseño (y no solo hasta el borde del relleno).

Un ejemplo:

<ListView
    android:id="@+id/list_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:divider="@android:color/transparent"
    android:dividerHeight="10.0sp"
    android:padding="16dip"
    android:clipToPadding="false"/>

android:clipToPadding es un atributo XML de ViewGroup, la clase base para diseños y vistas contenedor.

La llamada al método relacionada es:

public void setClipToPadding (boolean clipToPadding)
 386
Author: Gunnar Karlsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-23 01:08:25
View padding = new View(this);
padding.setHeight(20); // Can only specify in pixels unfortunately. No DIP :-(

ListView myListView = (ListView) findViewById(R.id.my_list_view);

myListView.addHeaderView(padding);
myListView.addFooterView(padding);

myListView.setAdapter(myAdapter);

El ListView anterior tendrá un relleno de encabezado y pie de página de 20 píxeles.

 19
Author: Jake Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-14 16:14:06

Apéndice a la respuesta de @Jakobud...

Mi ListView ya estaba haciendo uso de las propiedades android:divider/android:dividerHeight para crear espacios transparentes entre los elementos de ListView. Esto me permitió simplemente agregar las propiedades android:headerDividersEnabled y android:footerDividersEnabled y establecer las vistas de Encabezado y Pie de página en new View(Activity.this).

Una ligera simplificación para los casos en los que ya tiene la configuración de divisores en ListView.

 10
Author: greg7gkb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-23 04:52:58

Mi solución usando un ListFragment, basado en las soluciones de @ Jakobud y @ greg7gkb.

ListView listView = getListView();
listView.setDivider(null);
listView.setDividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height));
listView.setHeaderDividersEnabled(true);
listView.setFooterDividersEnabled(true);
View padding = new View(getActivity());
listView.addHeaderView(padding);
listView.addFooterView(padding);
 2
Author: hleinone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-01 16:12:42

La respuesta de@Gunnar Karlsson es buena, pero tiene un problema de que las vistas de las celdas se reciclen prematuramente cuando están completamente detrás del relleno, pero aún no están completamente fuera de la pantalla. La configuración de clipToPadding = false es responsable de esto y puede o no corregirse en una versión futura de Android.(Cuando se usa clipToPadding en ListView, los elementos se reciclan prematuramente)

Tengo una solución simple agradable sin efectos secundarios:

  1. Agregue un diseño externo (Lineal o Relativo) a su cell_design.xml
  2. En este diseño exterior agregue relleno (es decir, 10dip) para crear un "margen" alrededor de toda la celda. (N.b. solo el relleno funcionará, no el margen en el diseño exterior)
  3. En el conjunto ListView android:dividerHeight="-10dip", lo contrario de lo que está alrededor de la celda

En comparación con la otra respuesta, no hay necesidad de establecer el color del divisor. El relleno en las celdas superior e inferior estará presente, y el divisor negativo evitará divisores de doble altura en el medio.

 1
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:12