2012-04-04 9 views
27

Sto impostando un TextView con l'ID @android:id/empty per visualizzare un messaggio quando non ci sono elementi nello ListView. Tuttavia, questo TextView viene visualizzato anche se sono presenti articoli nello ListView, subito prima che gli elementi vengano visualizzati.Android che visualizza il testo quando ListView è vuoto

Come posso renderlo tale da essere visualizzato solo quando non ci sono elementi nello 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: sto usando un Loader e un SimpleCursorAdapter con un ListFragment.

+0

Basta impostare la visibilità TextView andato inizialmente !!Se listview ha alcuni dati, imposta visibilità visibile e imposta alcuni testi in modo programmatico – Rashiq

risposta

90

Immagino che tu stia usando un normale Fragment o Activity con uno ListView al suo interno. Se lo sei, devi aggiungere manualmente il layout vuoto allo ListView.

E.g.

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

Allora la vostra ListView utilizzerà automaticamente questo punto di vista, quando il suo adattatore è vuoto

Se si utilizza un ListActivity non c'è bisogno di chiamare setEmptyView() sul ListView dal momento che la ListActivity gestisce automaticamente per voi.

+0

Ho provato il codice che hai postato e ora funziona. Sto usando un ListFragment, sai perché ho bisogno di aggiungere il codice extra? Grazie. – Daniel

+9

Sì, in una ListFragment invece di usare una vista vuota dovresti chiamare setEmptyText ("lista vuota"); Non credo che ListFragment supporti automaticamente l'impostazione di una vista vuota. – dymmeh

+0

Quando lo aggiungo, ottengo questa eccezione "java.lang.IllegalStateException: il figlio specificato ha già un genitore. Devi prima chiamare removeView() sul genitore del figlio". Qualche idea su cosa sto facendo male? –

4

Ho avuto questo problema. Devi impostare il emptyView in modo esplicito nel tuo codice.

Cambia la tua TextView:

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

Poi nel onCreate():

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

Questo codice sopra presuppone che il ListView è in una LinearLayout.

9

Impostare un TextView e assegnare ad esso tutto ciò che si desidera visualizzare quando la ListView è vuota:

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

E nel mio file xml scriviamo il codice qui sotto

<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

ho usato ListFragment e ha avuto lo stesso problema Ho provato tutte le varianti da queste risposte, ma il problema non è stato risolto.

Così ho trovato la mia variante, per ignorare 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); 
    } 
} 

Spero che sarà utile per qualcuno.

2

So che questo è un po 'tardi, ma per farlo funzionare da XML, è necessario mettere un peso sul ListView e avere il vostro 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

C'è un good example di come farlo, che funziona impressionante:

quando si desidera mostrare un messaggio all'utente quando il ListView è vuoto, devi tenere a mente i seguenti 3 fasi:

  • nel XML in cui il ListView è dichiarato, creare un TextView (la TextView può essere all'interno di un LinearLayout se si vuole) proprio sotto il ListView
  • Set id 's la TextView come ‘emptyElement’
  • E all'interno l'attività, impostare la proprietà setEmptyView() al ListView

1- Creare un file XML che conterrà il ListView e denominarlo my_activity” e un'attività chiamata‘MyActivity’.

  1. Ora, nel xml appena creato "my_activity", sarà necessario impostare ListView. E subito sotto lo ListView, dovrai aggiungere a TextView. Questo sarà usato per visualizzare il messaggio vuoto.

Importante: TextView deve avere come id il nome seguente: "emptyElement". Questo nome è obbligatorio. Il messaggio non verrà visualizzato se si utilizza un altro nome.

Questo è il modo in xml “my_activity” dovrebbe essere simile:

<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. Crea un XML per la visualizzazione di oggetti (se l'elenco non è vuoto), e il nome "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. Creare una nuova classe Java per l'adattatore personalizzato che verrà utilizzato dal ListView e il nome “MyCustomAdapter”. Il codice per l'adattatore è scritto di seguito:

    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. Passare al MyActivity classe e aggiungere il codice qui sotto:

    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)); 
    } 
    } 
    
Problemi correlati