¿Ocultar la vista de pie de página en ListView?

78

Tengo un ListView. Los datos que hay detrás se obtienen de Internet, en conjuntos de 10 a 30 elementos, siempre que el usuario se desplaza hasta el final. Para indicar que está cargando más elementos, solía addFooterView()agregar una vista simple que muestra un mensaje "Cargando ..." y una ruleta. Ahora, cuando me quedo sin datos (no hay más datos para recuperar), quiero ocultar ese mensaje. Intenté hacer:

loadingView.setVisibility(View.GONE);

Desafortunadamente, si bien eso oculta la vista, le deja espacio. Es decir, termino con un gran espacio en blanco donde solía estar el mensaje "Cargando". ¿Cómo puedo ocultar correctamente esta vista?

No puedo usar removeFooterView()porque es posible que deba mostrarlo nuevamente, en cuyo caso no puedo addFooterView()volver a llamar porque ya se ha configurado un adaptador en el ListView, y no puede llamar addHeaderView()/ addFooterView()después de configurar un adaptador.

Felix
fuente

Respuestas:

84

Parece que puede llamar addHeaderView()/ addFooterView() after setAdapter() siempre que llame a uno de esos métodos al menos una vez antes . Esa es una decisión de diseño bastante pobre de Google, así que presenté un problema . Combina esto con removeFooterView()y tienes mi solución.

+1 para las otras dos respuestas que obtuve, son soluciones válidas (y posiblemente más correctas). La mía, sin embargo, es la más simple y me gusta la simplicidad, así que marcaré mi propia respuesta como aceptada.

Felix
fuente
6
Esto no parece funcionar para los encabezados. Puedo agregar un pie de página después de setAdapter, pero no un encabezado.
cottonBallPaws
1
+1 por ahorrar un ENORME dolor de cabeza. Me pregunto cuánto tiempo me habría tomado darme cuenta de que tenía que agregar el pie de página antes de configurar el adaptador. (tonto)
Ross Hambrick
Me he dado cuenta de que la posición de desplazamiento se restablece cuando quita la inferior, por lo que cuando se desplaza en exceso -> se elimina el pie de página antes de que termine de desplazarse en exceso, vuelve al final de la lista. ¿Te encontraste con esto?
Vadim Peretokin
No importa, me encontré con el mismo problema que tuvo littleFluffyKitty. Va a tener que ir con un adaptador personalizado.
Vadim Peretokin
¡Gran respuesta, simple! +100 por presentar los problemas con Google.
Tomasz
37

Intente establecer la altura del pie de página en 0px o 1px antes de ocultarlo. Alternativamente, envuelva la vista de pie de página en una wrap_contentaltura FrameLayouty oculte / muestre la vista interior, dejando FrameLayoutvisible; la altura debe envolver correctamente entonces.

Yoni Samlan
fuente
¿Cómo se fuerza a establecer la altura de la vista? Intenté setMinimumHeight (0); antes de esconderse pero no parece funcionar. Lo configuré en GONE, pero el espacio de la celda aún queda atrás.
Maurice
La altura y el ancho son parámetros de diseño, por lo que debe establecer el objeto LayoutParameters para la vista con el nuevo ancho / alto. Vea esta respuesta SO: stackoverflow.com/a/2767142/59058 . Básicamente, el ancho, el alto y los márgenes son propiedades que realmente se aplican al contenedor de la vista, no a la vista en sí, por lo que usa un objeto LayoutParameter vinculado a los padres para definirlos.
Yoni Samlan
No creo que eso funcione para un encabezado, obtuve nulo en un encabezado que estaba adjunto y llamado getLayoutParams () para.
Vadim Peretokin
5

en mi caso addFooterView / removeFooterView () causa algunos artefactos. Y encontré otra solución. Usé FrameLayout como FooterView. Y cuando quiero agregar Footer, llamé mFrameFooter.addView (myFooter); y mFrameFooter.removeAllViews (); para quitar.

FrameLayout frameLayout = new FrameLayout(this);
listView.addFooterView(frameLayout);
......
......
//For adding footerView
frameLayout.removeAllViews();
frameLayout.addView(mFooterView);
//For hide FooterView
frameLayout.removeAllViews();
preceptrón
fuente
Trabajando como un encanto. Debería ser la respuesta aceptada :)
King of Masses
4

La biblioteca Droid-Fu tiene una clase diseñada para mostrar y ocultar un pie de página de carga: ListAdapterWithProgress .

rwat
fuente
2
Con un ejemplo de uso, esta respuesta habría ganado más votos.
Subin Sebastian
4

Funciona bien en mi proyecto:

1.Añadir primero la vista de pie de página

mListView.addFooterView(mFooterView); mListView.setAdapter(mAdapter);

2.Establecer visibilidad

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, 0, 0, 0);

3.Configurar la invisibilidad

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, -1*mFooterView.getHeight(), 0, 0);

Geek4IT
fuente
2

Como señaló @YoniSamlan, se puede lograr de una manera sencilla. Tienes que especificar

android:layout_height="wrap_content" 

en ViewGroup que contiene el botón "Cargar más". No tiene que ser FrameLayout, vea a continuación un ejemplo simple de trabajo que usa LinearLayout.

Ambas imágenes muestran una pantalla que se desplaza hasta el final. El primero tiene un pie de página visible que envuelve el botón "cargar más". Las segundas imágenes muestran que el pie de página se colapsa si configura la visibilidad del botón en GONE.

Puede volver a mostrar el pie de página (dentro de alguna devolución de llamada) cambiando la visibilidad:

loadMore.setVisibility(View.VISIBLE);  // set to View.GONE to hide it again

listView con pie de página visible listView sin pie de página

Realice la inicialización de listView como de costumbre

    // Find View, set empty View if needed
    mListView = (ListView) root.findViewById(R.id.reservations_search_results);
    mListView.setEmptyView(root.findViewById(R.id.search_reservations_list_empty));

    // Instantiate footerView using a LayoutInflater and add to listView
    footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
            .inflate(R.layout.load_more_footer_view, null, false);
    // additionally, find the "load more button" inside the footer view
    loadMore = footerView.findViewById(R.id.load_more);
    loadMore.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fetchData();
        }
    });

    // add footer view to the list
    mListView.addFooterView(footerView);

    // after we're done setting the footerView, we can setAdapter
    adapter = new ReservationsArrayAdapter(getActivity(), R.layout.list_item_reservations_search, reservationsList);
    mListView.setAdapter(adapter);

load_more_footer_view.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="wrap_content">

<Button
    android:id="@+id/load_more"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="9dp"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@drawable/transparent_white_border"
    android:textColor="@android:color/white"
    android:text="@string/LOAD_MORE"/>

kouretinho
fuente
2

Debería ser un error de Android.

No es necesario eliminar o agregar una vista de pie de página de forma dinámica. Solo necesita crear un diseño principal de altura no especificado (inflarlo desde un archivo xml o crearlo programáticamente) y luego agregar la vista que desea ocultar o mostrar en él.

Y puede configurar la vista, pero NO el diseño principal, en VISIBLE o GONE o algo más ahora. Esto funciona para mi.

Ligero
fuente
0

Usado

footer.removeAllViews();

Esto no elimina el pie de página, pero elimina a los niños. De nuevo hay que repoblar a los niños. Puede comprobar por

footer.getChildCount()<2
Rahul
fuente
0

También descubrí que es posible llamar onContentChanged()(si lo usa ListActivity) para forzar la recreación ListViewsi necesito agregarlos HeaderViewdespués de la setAdapter()llamada, pero es un truco muy feo.

Átomo
fuente
0

He creado un ListView que maneja esto. También tiene una opción para usar EndlessScrollListener que he creado para manejar vistas de lista interminables, que carga datos hasta que no hay más datos para cargar.

Puedes ver estas clases aquí:

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Ayudante para hacer posible el uso de características sin ampliar desde SimpleListViewWithLoadingIndicator.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java : escucha que comienza a cargar datos cuando el usuario está a punto de llegar al final de ListView.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Puede utilizar esta clase directamente o ampliarla.

Fernando Camargo
fuente
0

Tengo una pequeña forma de hackear para resolver este problema en todas partes. Coloque la vista de lista y la vista de pie de página (solo diseño secundario) en el diseño principal como LinnearLayout, recuerde que la vista de pie de página debajo de la vista de lista.

Controle esta vista de pie de página desaparecida y visibilidad como vista normal. ¡Y hecho!

cuasodayleo
fuente
0

primero estoy agregando mi pie de página a la vista de lista, así

listView.addFooterView(Utils.b);

Luego, al hacer clic en el botón, elimino la vista,

listView.removeFooterView(Utils.b);

Estoy agregando el pie de página cada vez que presiono el async, y no hay una entrada duplicada.También podría verificar el recuento y así es así,

if(listView.getFooterViewsCount() > 0){//if footer is added already do something}
Syeda
fuente
-1

Cuando desee eliminar el pie de página en ListViewsimplemente llame

listView.addFooterView(new View(yourContext)); 

Agregará una vista vacía ficticia que no reservará ningún espacio

Kareem
fuente
1
la documentación dice "Si se llama a addFooterView más de una vez, las vistas aparecerán en el orden en que se agregaron".
max4ever