2012-04-04 33 views
27

Estoy configurando un TextView con el id @android:id/empty para mostrar un mensaje cuando no hay elementos en el ListView. Sin embargo, este TextView aparece incluso si hay elementos en el ListView, justo antes de que aparezcan los elementos.Android que muestra texto cuando ListView está vacío

¿Cómo puedo hacer que solo se muestre cuando no hay elementos en el ListView?

<?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="match_parent" 
    android:orientation="vertical" > 

<ListView 
    android:id="@android:id/list" 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    android:dividerHeight="1dp" > 
</ListView> 

<TextView 
    android:id="@android:id/empty" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/empty_list" /> 

</LinearLayout> 

PS: Estoy usando un Loader y una SimpleCursorAdapter con un ListFragment.

+0

Sólo hay que establecer la visibilidad TextView ido inicialmente !!Si listview tiene algunos datos, establezca la visibilidad visible y establezca un texto programáticamente – Rashiq

Respuesta

90

Supongo que está usando un Fragment normal o Activity con un ListView dentro de él. Si es así, debe agregar el diseño vacío al ListView manualmente.

E.g.

ListView lv = (ListView)findViewById(android.R.id.list); 
TextView emptyText = (TextView)findViewById(android.R.id.empty); 
lv.setEmptyView(emptyText); 

Luego, su ListView utilizará automáticamente este punto de vista cuando el adaptador está vacía

Si está utilizando un ListActivity que no es necesario llamar a setEmptyView() en el ListView ya que el ListActivity gestiona automáticamente por usted.

+0

Probé el código que publicó y ahora funciona. Estoy usando un ListFragment, ¿sabes por qué necesitaba agregar el código adicional? Gracias. – Daniel

+9

Sí, en un ListFragment en lugar de usar una vista vacía debe llamar a setEmptyText ("empty listview"); No creo que ListFragment permita establecer una vista vacía automáticamente. – dymmeh

+0

Cuando lo agrego, recibo esta excepción "java.lang.IllegalStateException: el elemento secundario especificado ya tiene un elemento primario. Primero debe llamar a removeView() en el elemento primario del elemento secundario." ¿Alguna pista de lo que estoy haciendo mal? –

4

Tuve este problema. Tienes que configurar emptyView explícitamente en tu código.

Cambiar la TextView:

<TextView 
    android:id="@android:id/emptyResults" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/empty_list" /> 

Luego, en el onCreate():

listViewResults = (ListView) findViewById(R.id.list); 
listViewResults.setEmptyView((LinearLayout) findViewById(R.id.emptyResults)); 

Este código anterior supone que su ListView está en un LinearLayout.

9

Conjunto un TextView y asignar a él lo que desea mostrar cuando el ListView está vacía:

ProjectListAdapter projectListAdapter = new ProjectListAdapter(); 
TextView empty=(TextView)findViewById(R.id.empty); 
projectsListView.setEmptyView(empty); 

Y en mi archivo XML que escribir el código de abajo

<TextView 
     android:id="@+id/empty" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:gravity="center" 
     android:text="Your text here" 
     android:textColor="#FFFFFF" /> 
3

que utilizan ListFragment y tenía el mismo problema Probé todas las variantes de estas respuestas, pero el problema no se resolvió.

Así que encontré mi variante, para anular setEmptyText():

public class NewsFragment extends ListFragment{ 
    private TextView emptyText; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
     //... 

     emptyText = (TextView)view.findViewById(android.R.id.empty); 

     //... 
    } 

    @Override 
    public void setEmptyText(CharSequence text) { 
     emptyText.setText(text); 
    } 
} 

Esperamos que sea útil para alguien.

2

Sé que esto es un poco tarde, pero para que funcione a partir de XML, es necesario poner un peso en su ListView y tener su TextView match_parent

<?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="match_parent" 
    android:orientation="vertical" > 

<ListView 
    android:id="@android:id/list" 
    android:layout_width="wrap_content" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    android:dividerHeight="1dp" > 
</ListView> 

<TextView 
    android:id="@android:id/empty" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:text="@string/empty_list" /> 

</LinearLayout> 
0

Hay una good example de cómo hacerlo, que funciona increíble:

cuando se desea mostrar un mensaje al usuario cuando el ListView es vacío, hay que tener en cuenta los siguientes 3 pasos:

  • en el XML, donde se declara la ListView, crear un TextView (el TextView puede estar dentro de un LinearLayout si quieres) derecho por debajo de la ListView
  • Set Identificación del TextView 's como ‘emptyElement’
  • Y dentro de la actividad, establecer la propiedad setEmptyView() a la ListView

1- Crear un xml que ejercerá la ListView y el nombre de my_activity” y una actividad denominada‘MyActivity’.

  1. Ahora, en el recién creado xml "my_activity", tendrá que configurar el ListView. Y justo debajo del ListView, deberá agregar a TextView. Esto se usará para mostrar el mensaje vacío.

Importante: La TextView debe tener como identificación el siguiente nombre: “emptyElement”. Este nombre es obligatorio. El mensaje no se mostrará si usa otro nombre.

Esta es la forma en xml “my_activity” debe verse como:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    tools:context=".MyActivity"> 

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

    <TextView android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/emptyElement" 
     android:text="The list is empty" 
     android:textStyle="bold" 
     android:textSize="15sp" 
     android:visibility="gone" 
     android:layout_centerInParent="true" 
      android:textColor="@android:color/darker_gray"/> 

</RelativeLayout> 
  1. Crear un xml para la visualización de objetos (cuando la lista no está vacía), y el nombre es "list_item".

    <TextView android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:id="@+id/list_item_text_view" 
        android:textSize="20sp" 
        android:padding="10dp" 
        android:layout_marginLeft="5dp"/> 
    

  2. Crear una nueva clase Java para el adaptador personalizado que será utilizado por el ListView y el nombre “MyCustomAdapter”. El código para el adaptador se escribe a continuación:

    import android.content.Context; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.BaseAdapter; 
    import android.widget.TextView; 
    import java.util.ArrayList; 
    
    
    public class MyCustomAdapter extends BaseAdapter { 
    private ArrayList<String> mListItems; 
    private LayoutInflater mLayoutInflater; 
    
    public MyCustomAdapter(Context context, ArrayList<String> arrayList){ 
    
        mListItems = arrayList; 
    
        //get the layout inflater 
        mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 
    
    @Override 
    public int getCount() { 
        //getCount() represents how many items are in the list 
        return mListItems.size(); 
    } 
    
    @Override 
    //get the data of an item from a specific position 
    //i represents the position of the item in the list 
    public Object getItem(int i) { 
        return null; 
    } 
    
    @Override 
    //get the position id of the item from the list 
    public long getItemId(int i) { 
        return 0; 
    } 
    
    @Override 
    
    public View getView(int position, View view, ViewGroup viewGroup) { 
    
        // create a ViewHolder reference 
        ViewHolder holder; 
    
        //check to see if the reused view is null or not, if is not null then reuse it 
        if (view == null) { 
         holder = new ViewHolder(); 
    
         view = mLayoutInflater.inflate(R.layout.list_item, null); 
         holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view); 
    
         // the setTag is used to store the data within this view 
         view.setTag(holder); 
        } else { 
         // the getTag returns the viewHolder object set as a tag to the view 
         holder = (ViewHolder)view.getTag(); 
        } 
    
        //get the string item from the position "position" from array list to put it on the TextView 
        String stringItem = mListItems.get(position); 
        if (stringItem != null) { 
         if (holder.itemName != null) { 
          //set the item name on the TextView 
          holder.itemName.setText(stringItem); 
         } 
        } 
    
        //this method must return the view corresponding to the data at the specified position. 
        return view; 
    
    } 
    
    /** 
    * Static class used to avoid the calling of "findViewById" every time the getView() method is called, 
    * because this can impact to your application performance when your list is too big. The class is static so it 
    * cache all the things inside once it's created. 
    */ 
    private static class ViewHolder { 
    
        protected TextView itemName; 
    
    } 
    } 
    
  3. Ahora ve a MyActivity clase y añadir el código de abajo:

    import android.app.Activity; 
    import android.os.Bundle; 
    import android.widget.ListView; 
    import java.util.ArrayList; 
    import java.util.List; 
    
    
    public class MyActivity extends Activity { 
    
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.my_activity); 
    
        ListView listView = (ListView) findViewById(R.id.listView); 
    
        // Create an empty array list of strings 
        List<String> items = new ArrayList<String>(); 
    
        // Set the adapter 
        MyCustomAdapter adapter = new MyCustomAdapter(items); 
        listView.setAdapter(adapter); 
    
        // Set the emptyView to the ListView 
        listView.setEmptyView(findViewById(R.id.emptyElement)); 
    } 
    } 
    
Cuestiones relacionadas