Desplazamiento síncrono de un encabezado ListView parcial
Esta pregunta es muy específica, lo que estoy tratando de hacer (con una vista de lista) se describe con gran detalle en el siguiente artículo: http://www.pushing-pixels.org/2011/07/18/android-tips- And-tricks-synchronized-scrolling.html
Gracias @kaushal trivedi por el enlace
- Agregar elemento a ListView sin recargar
- Cómo ordenar una vista de lista en orden alfabético
- Multiline EditText en los problemas de desplazamiento de RecyclerView
- Actualización de la vista Lista de Android
- ¿Cómo puede escuchar los eventos de clic en un ListView que se producen fuera de los elementos de la lista?
Detalles: Tengo una aplicación de Android que estoy trabajando en que utiliza una vista de lista con un adaptador personalizado. El Listview Contiene un encabezado personalizado de una altura no fija. También tenga en cuenta que los elementos de la lista también son de altura variable. Mi objetivo es imitar el efecto producido en la última aplicación de Gmail (como un ejemplo) donde cuando se está viendo un correo electrónico, y desplazarse más allá del encabezado, se pega en la parte superior de la pantalla justo debajo de la barra de acción y el contenido continúa Desplácese debajo de él. Lo que me gustaría hacer, es pegar la mitad inferior de mi encabezado a la parte superior de la pantalla.
Mi razonamiento inicial era crear una vista invisible fijada en la ubicación deseada, y cuando el usuario se desplaza hacia o más allá de esa ubicación, haga que la vista sea visible. El problema en esta lógica, es que necesito la altura exacta de desplazamiento de píxel, que después de muchos intentos que he determinado muy difícil de hacer. El problema exacto que encontré es, no es posible de lo que puedo reunir para recuperar el nivel de píxeles Y-scroll en un evento onScroll, sólo he sido capaz de recuperar el valor en el evento onScrollStateChanged. Lo cual, como se ha descrito anteriormente, no conseguirá la funcionalidad deseada.
Trabajar con el parámetro onScroll "int firstVisibleItem, int visibleItemCount, int totalItemCount" también no es una opción debido al hecho de que el contenido que quiero "stick" no es el tamaño de un elemento de lista, sino una fracción del tamaño de El encabezado de altura variable.
¿Hay una manera correcta de lograr este efecto? Mi nivel actual de minSDK es 10.
Actualización 10/10/13
Hice algunos progresos. El siguiente código sincroniza la vista flotante de posición Y que tengo en la pantalla con la vista de lista. B es la visión que estoy estableciendo como un ejemplo.
NOTA: Se utiliza en el evento onScroll
de la vista de lista.
View c = view.getChildAt(0); if (c != null) { int currY = c.getTop(); int diffY = currY - lastY; lastY = currY; b.setTop(b.getTop() + diffY); }
Ahora el problema es, el encabezado de mi lista es una altura no fija como dije anteriormente. Así que necesito obtener la altura del encabezado y aplicar un desplazamiento a "b" para colocarlo en la parte inferior del encabezado de lista flotando por encima de la lista.
Este es el código que he probado hasta ahora.
header.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
El problema aquí nos header.getMeasuredHeight();
Siempre se resuelve al mismo valor sin importar cuan alta sea la altura real.
Entiendo que no puedo conseguir la altura hasta después de que se muestre. ¿Hay una manera de obtener ese valor y establecer el desplazamiento después de que se representa?
Actualización 10/11/13
Respondí a mi última pregunta tan pronto como desperté esta mañana.
Mientras que el código View.measure()
devolvió una altura. Parece ser la altura predeterminada de la vista, asumiendo que no había texto (que en última instancia, estirar la vista). Así que utilicé el siguiente evento para escuchar cuando la vista se muestra, y luego registrar su altura real (que funciona exactamente como yo esperaba :))
ViewTreeObserver vto = header.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { b.setY(header.getMeasuredHeight() - 80); //80 is a temp offset } });
Tengo que ir a trabajar pronto y siendo que todavía no he logrado totalmente el efecto deseado, no voy a marcar esto como contestado todavía. Espero poder sentarme y terminar esto en el día siguiente o dos. Todavía estoy abierto a sugerencias sobre mejores maneras de hacer esto.
- Obtener elementos seleccionados de ListView con casilla de verificación
- Scroller no muestra el resto del contenido listView
- Cómo administrar deshacer después de deslizar para eliminar en android ListView?
- ListView no dispara setOnLongClickListener, sólo setOnItemClickListener
- Filtrado personalizado ArrayAdapter en ListView
- Obtener NullPointerException en ListView personalizado
- Obtener el elemento seleccionado al hacer doble clic en el elemento de lista
- Cómo obtener datos de adaptador personalizado en ListView?
Bueno, así que después de mucho tiempo e investigación, he encontrado una respuesta a mi pregunta.
Primero, gracias @kaushal por este enlace: http://www.pushing-pixels.org/2011/07/18/android-tips-and-tricks-synchronized-scrolling.html
Mi solución terminó siendo algo complejo. Así que en vez de tratar de describirlo aquí, hice una aplicación de ejemplo y lo publiqué aquí: https://github.com/gh123man/Partial-Header-ListView-Scroll-Sync
El archivo específico que contiene el código de la solución está aquí: https://github.com/gh123man/Partial-Header-ListView-Scroll-Sync/blob/master/src/com/example/partialheaderlistplayscrollsync/MainActivity.java
- Cómo saber cuando la página siguiente / anterior ha cargado completamente en el efecto de curl de página por harism?
- ¿Cómo puedo corregir o depurar "Error: Android Packager: No puedo crear una nueva clave o keystore" en IntelliJ