Mostrar vista vacía cuando ListView está vacío

135

Por alguna razón, la vista vacía, una TextView en este caso, siempre aparece incluso cuando ListView no está vacía. Pensé que ListView detectaría automáticamente cuándo mostrar la vista vacía.

<RelativeLayout android:id="@+id/LinearLayoutAR"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent">
    <ListView android:id="@+id/ARListView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"></ListView>
    <ProgressBar android:id="@+id/arProgressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"></ProgressBar>
    <!-- Here is the view to show if the list is emtpy -->
    <TextView android:id="@id/android:empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="No Results" />
</RelativeLayout>

¿Cómo puedo conectar la vista vacía correctamente?

Sheehan Alam
fuente

Respuestas:

135

Debería ser así:

<TextView android:id="@android:id/empty"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="No Results" />

Tenga en cuenta el atributo id .

Nathan Schwermann
fuente
75
tienes que estar usando ListViewActivity para que funcione de esta manera.
Nathan Schwermann
2
oh ya veo, mi ListView está realmente dentro de un ViewFlipper. ¿Hay alguna otra manera de presentar la vista cuando la lista está vacía?
Sheehan Alam
11
ha implementado la lógica usted mismo, eche un vistazo al código fuente de ListViewActivity para ver cómo lo hacen, o cuando realice su consulta, verifique si está vacía, si es así, configure su vista de texto en VISIBLE, de lo contrario, configúrelo en GONE
Nathan Schwermann
44
usar la vista de texto cuando está usando un adaptador personalizado no funciona.
user590849
3
@schwiz falso! no necesita una ListViewActivity para usar la funcionalidad vacía.
Buffalo
187

Al ampliar FragmentActivityo Activityy no ListActivity , usted querrá echar un vistazo a:

ListView.setEmptyView ()

appsthatmatter
fuente
alguna idea de cómo hacer eso en inventor de aplicaciones?
JinSnow
118

Como dice appsthatmatter, en el diseño algo así como:

<ListView android:id="@+id/listView" ... />
<TextView android:id="@+id/emptyElement" ... />

y en la Actividad vinculada:

this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.emptyElement));

También funciona con un GridView ...

Remolino
fuente
44
Después de al menos una hora de probar varias cosas y no tener nada que funcione (mostrando el texto "vacío" además de los datos en la vista de lista), esto funcionó para mí cuando uso ListView en una actividad en lugar de extender ListActivity. Gracias Eddy!
Evan R.
¿Debo hacer que TextView esté oculto o algo así?
Harsha MV
11
@Harsha Android: la visibilidad = "ido"
scragar
42

Probé todas las soluciones anteriores. Se me ocurrió resolver el problema. Aquí estoy publicando la solución completa.

El archivo xml :

<RelativeLayout
    android:id="@+id/header_main_page_clist1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:paddingBottom="10dp"
    android:background="#ffffff" >

    <ListView
        android:id="@+id/lv_msglist"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/divider_color"
        android:dividerHeight="1dp" />

    <TextView
        android:id="@+id/emptyElement"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="NO MESSAGES AVAILABLE!"
        android:textColor="#525252"
        android:textSize="19.0sp"
        android:visibility="gone" />
</RelativeLayout>

TextView ( "@ + id / emptyElement" ) es el marcador de posición para la vista de lista vacía.

Aquí está el código para la página de Java:

lvmessage=(ListView)findViewById(R.id.lv_msglist);
lvmessage.setAdapter(adapter);
lvmessage.setEmptyView(findViewById(R.id.emptyElement));

Recuerde colocar el emptyView después de vincular el adaptador a listview.Mine no funcionaba por primera vez y después de mover setEmptyView después de setAdapter ahora funciona.

Salida:

ingrese la descripción de la imagen aquí

kgandroid
fuente
1
esto funcionó para mí después de agregar android:layout_below="@+id/lv_msglist"para emptyElement
Behnam Heydari
16

Le recomiendo que use ViewStubs como este

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <ViewStub
        android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout="@layout/empty" />
</FrameLayout>

Vea el ejemplo completo de Cyril Mottier

LOG_TAG
fuente
8
<ListView android:id="@+id/listView" ... />
<TextView android:id="@+id/empty" ... />
and in the linked Activity:

this.listView = (ListView) findViewById(R.id.listView);
this.listView.setEmptyView(findViewById(R.id.empty));

Esto funciona claramente con FragmentActivity si está utilizando la biblioteca de soporte. Probé esto compilando para API 17 es decir, imagen 4.2.2

Yaojin
fuente
7

Código de actividad, es importante extenderlo ListActivity.

package com.example.mylistactivity;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import com.example.mylistactivity.R;

// It's important to extend ListActivity rather than Activity
public class MyListActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylist);

        // shows list view
        String[] values = new String[] { "foo", "bar" };

        // shows empty view
        values = new String[] { };

        setListAdapter(new ArrayAdapter<String>(
                this,
                android.R.layout.simple_list_item_1,
                android.R.id.text1,
                values));
    }
}

Diseño xml, la identificación en ambas vistas es importante.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <!-- the android:id is important -->
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>

    <!-- the android:id is important -->
    <TextView
        android:id="@android:id/empty"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="i am empty"/>
</LinearLayout>
Mizipzor
fuente
7

Solo para agregar que realmente no necesita crear nuevas ID, algo como lo siguiente funcionará.

En el diseño:

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@android:id/list"/>

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@android:id/empty"
    android:text="Empty"/>

Luego en la actividad:

    ListView listView = (ListView) findViewById(android.R.id.list);
    listView.setEmptyView(findViewById(android.R.id.empty));
Luís Ramalho
fuente
4

Tuve este problema Tuve que hacer que mi clase extendiera ListActivity en lugar de Activity y cambiar el nombre de mi lista en el XML paraandroid:id="@android:id/list"

Mate
fuente
2

Una solución programática será:

TextView textView = new TextView(context);
textView.setId(android.R.id.empty);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setText("No result found");
listView.setEmptyView(textView);
Mika
fuente
-3

Primero verifique que la lista contiene algunos valores:

if (list.isEmpty()) {
    listview.setVisibility(View.GONE);
}

Si está bien, use:

else {
     listview.setVisibility(View.VISIBLE);
}
Avnish Kumar
fuente
¿te importaría elaborar más a fondo qué es un list?
Roy Lee
Es una ArrayList <xyz>
Avnish Kumar
Objeto [] respuesta = Utility.parseStationresponce (objeto); int statusCode = (entero) respuesta [0]; @SuppressWarnings ("sin marcar") ArrayList <Stations> list = (ArrayList <Stations>) respuesta [2];
Avnish Kumar
Bien, te sugiero que digas eso como parte de tu respuesta en lugar de comentarios. Esto es importante para que otros comprendan el contexto específico de lo que está escribiendo. Además, también es mejor si puede relacionar su respuesta con la pregunta de OP. Finalmente, bienvenido a SO.
Roy Lee