Ocultar la vista de encabezado en ListView
Estoy tratando de añadir una vista de cabecera a mi lista, y esconderlo todo el tiempo a menos que nos desplácese a él (como el mecanismo pull-to-refresh). El problema es: si la lista no es lo suficientemente alta como para llenar la pantalla, la vista de encabezado se muestra en la parte superior de la lista.
¿Hay alguna forma de ocultarlo y hacerlo visible sólo cuando nos desplácese hasta él? He estado intentando muchas cosas, pero no puedo encontrar una manera buena y sencilla de hacerlo.
- ¿Qué es VerticalScrollExtent en Android ScrollView?
- Android - Cómo configurar el relleno para TextView en ListView o ExpandableListView
- Android Drawer Layout está mostrando contenido de fragmentos
- ¿Es mejor recrear el adaptador listview o borrar y repoblar?
- ¿Cómo puedo usar layout_weight en RecyclerView o Vista de elemento ListView para que los elementos de igual altura llenen el espacio disponible en la pantalla?
Gracias
- Desaparecer divisor en ListView cuando ArrayAdapter.isEnabled devuelve false
- Cuando los listitems se desplazan rápidamente, setOnScrollListener no funciona
- Android: ¿cómo actualizar el contenido de ListView?
- ¿Por qué obtengo NullPointerException cuando uso setCurrentText o setText para TextSwitcher?
- SwipeRefreshLayout con múltiples ListViews
- Pasar de una vista de lista a una vista de cuadrícula
- ¿Cómo puedo crear un ListView con divisiones de línea punteadas / punteadas en Android?
- Listview con diseño de tabla
Esta es una entrada en el blog que describe una forma sencilla de ocultar y mostrar la vista de encabezado.
La idea es poner el contenido que desea ocultar en un LinearLayout
que lo envuelve, y ocultar sólo el contenido . De esta manera, el envolvente LinearLayout
se colapsará cuando su contenido esté oculto, lo que resultará en un headerView técnicamente todavía presente, pero 0dip high.
Nota: Si tratas de ocultar el contenido sin el diseño adjunto, quedarás con espacio no deseado en la vista de encabezado.
Un ejemplo de diseño con una ruleta que representa el contenido:
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ProgressBar android:id="@+id/spinner" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
A continuación, puede ocultar la ruleta (contenido) de la siguiente manera:
spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE);
Puede ver ListView.setOverscrollHeader () o ListView.setOverscrollFooter () . ¿Es este el comportamiento que buscas?
Si no, ¿podría publicar algún código que muestre lo que tiene hasta ahora?
EDITAR:
Ok, así que miré en Overscrolling encabezados / pies de página y tienes razón, no creo que eso es lo que quieres en absoluto.
En su lugar probablemente debería buscar en el mecanismo Pull to Refresh de la aplicación de Twitter que otros han tratado de emular. Usted puede mirar en las respuestas de esta pregunta .
La respuesta más prometedora parece ser el ListView personalizado escrito por Johan Nilson, cuyo código se puede encontrar aquí:
https://github.com/johannilsson/android-pulltorefresh
EDIT # 2:
He echado un vistazo a la lista personalizada PullToRefresh ListView y lo que quieres hacer es probablemente posible, aunque no necesariamente fácil. Permítanme explicar.
El PullToRefreshListView es esencialmente un hack que explota el encabezado opcional en ListViews estándar. La opción "Pull To Refresh" que se ve es realmente el encabezado de ListView. Cuando se visualiza la lista, se ejecuta esta línea:
setSelection(1);
Esto desplaza la lista al primer elemento de la lista, ocultando el encabezado. Cuando la lista es lo suficientemente corta para ser visualizada completamente en la pantalla, no es necesario desplazarse, de ahí el botón "Toque para actualizar".
Cuando este "Toque para actualizar" está visible, el mecanismo de pull to refresh está deshabilitado, pero es bastante fácil arreglarlo. El efecto pull to refresh se logra aumentando el relleno superior de la vista de encabezado, de modo que parece que estás tirando de la lista (cuando realmente es más exacto decir que el encabezado está presionando el resto de la lista).
La cantidad de relleno añadido se controla mediante la función applyHeaderPadding () en la línea 199 del código fuente. En esa función hay una instrucción if en la línea 220 que sólo aplica el relleno cuando la lista está en el modo RELEASE_TO_REFRESH:
if (mRefreshState == RELEASE_TO_REFRESH) { //Some code that eventually adds padding to the header... }
Si elimina esta condición o la cambia para aplicar relleno sin importar el modo en el que se encuentre, puede arrastrar para actualizar incluso si la lista es corta y el encabezado dice "Toque para actualizar"
if (true) { //Some code that eventually adds padding to the header... }
Sin embargo, esto no crea exactamente el efecto que está buscando. Si la lista es corta, puede arrastrarla hacia abajo para actualizar, pero el encabezado "Toque para actualizar" todavía se muestra. Ahora el problema es "¿Cómo puedo ocultar el encabezado hasta que comience el movimiento de arrastre?" Este es un problema difícil por sí mismo, con varias preguntas de desbordamiento de pila dedicadas a ella.
Si desea un encabezado, debe agregarlo ANTES de configurar el adaptador para el ListView, de lo contrario obtendrá todo tipo de errores.
Tuve un cierto éxito con esto, pero no he llegado con nada estable, porque mi solución es una especie de hack desagradable en la parte superior de la ya hackeado PullToRefreshListView. Establecer un FrameLayout vacío como el encabezado y agregó el tirón original para actualizar el encabezado a ese diseño de trama. Luego, mientras arrastraba la lista, editaba la altura en LayoutParameters del Layout de marco para crecer y encogerse de forma similar al relleno originalmente. Es una especie de trabajo, pero eventualmente fuerza cerca, y no he descubierto por qué todavía.
De todos modos, si lo tengo a trabajar voy a publicar el código, de lo contrario alguien más sabio que yo podría proponer una solución basada en la información que acaba de proporcionar.
Aquí hay una solución para el actual PullToRefreshListView (actualizado el 4 de noviembre de 2011):
https://github.com/johannilsson/android-pulltorefresh
Basado en el artículo Hiding Header Views:
http://pivotallabs.com/users/joe/blog/articles/1759-android-tidbits-6-22-2011-hiding-header-views
1) Copie pull_to_refresh_header.xml desde el res/layout
de la biblioteca hasta el res/layout
de su aplicación.
2) Edite el pull_to_refresh_header.xml
su aplicación. Envuelva Top RelativeLayout en un LinearLayout y, a continuación, ajuste el LinearLayout en un RelativeLayout de nuevo. ¿Por qué? El diseño Topmost debe ser RelativeLayout porque eso es lo que se espera en el código, el diseño de segundo nivel debe ser LinearLayout porque ese es el único diseño que se colapsa con View.GONE. El diseño de tercer nivel debe ser el mismo que el original de primer nivel RelativeLayout (excepto id) para preservar la apariencia.
3) Preserve el mismo id en la parte superior de RelativeLayout (pull_to_refresh_header), dé al segundo nivel LinearLayout un id de su elección, dé tercer nivel RelativeLayout otro id (pull_to_refresh_header2 por ejemplo).
4) Mueva todo el relleno desde el último RelativoLayout al segundo RelativoLayout.
5) En su código use findViewById y su ID de LinearLayout para establecer la visibilidad de View.GONE. El LinearLayout se derrumbará y si movió todos los valores de relleno apropiadamente a RelativeLayout interno, el encabezado no debería tener espacio en absoluto.