2010-05-11 10 views
38

Tengo problemas para usar el método setEmptyView. Intenté implementarlo en GridView y ListView, pero ninguno de los dos funcionó. Aquí un bloque de código de ejemplo:Uso correcto de setEmtpyView en AdapterView

networkGames = (GridView) baseLayer.findViewById(R.id.all_game_grid_network); 
networkGames.setBackgroundResource(R.drawable.game_border); 
networkGames.setSelector(R.drawable.game_active_border); 
networkGames.setOnItemClickListener(new NetworkGameListener()); 
networkGames.setEmptyView(View.inflate(baseLayer, R.drawable.no_network_games, null)); 
networkGames.setAdapter(new NetworkAdapter()); 

El adaptador de red no contiene elementos:

private class NetworkAdapter extends BaseAdapter { 

     /* (non-Javadoc) 
     * @see android.widget.Adapter#getCount() 
     */ 
     @Override 
     public int getCount() { 
      return 0; 
     } 

     /* (non-Javadoc) 
     * @see android.widget.Adapter#getItem(int) 
     */ 
     @Override 
     public Object getItem(int position) { 
      return null; 
     } 

     /* (non-Javadoc) 
     * @see android.widget.Adapter#getItemId(int) 
     */ 
     @Override 
     public long getItemId(int position) { 
      return 0; 
     } 

     /* (non-Javadoc) 
     * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) 
     */ 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      return null; 
     } 

    } 

también intentó llamar networkGames.setAdapter (nulo), pero esto no funciona bien. Mi emtpyView se ve así:

<LinearLayout 
android:id="@+id/LinearLayout01" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
xmlns:android="http://schemas.android.com/apk/res/android"> 
    <TextView 
    android:text="There are currently no network games available. Start a new one." 
    android:id="@+id/TextView01" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center"> 
    </TextView> 
</LinearLayout> 

Realmente no sé lo que estoy haciendo mal. También leí varios tutoriales, pero ninguno de ellos resolvió ningún problema.

Respuesta

93

Debe agregar esta misma vista en el diseño en el que ha agregado AdapterView.

AdapterView solo cambia su visibilidad en función del contenido del adaptador.

Editado:
Siguiendo el diseño y el código funciona bien:


<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ListView 
     android:layout_width="fill_parent" 
     android:layout_height="300dip" 
     android:id="@+id/list_view" /> 
    <TextView 
     android:id="@+id/empty_list_view" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="List view is empty" 
     android:visibility="gone" /> 
</LinearLayout>

Código:

ListView listView = (ListView) findViewById(R.id.list_view); 
listView.setEmptyView(findViewById(R.id.empty_list_view)); 
listView.setAdapter(new ArrayAdapter(this, R.layout.selected_spinner_view, new ArrayList()));

+0

agregué el diseño anterior al final del diseño donde defino mi gridview. pero sin embargo no se muestra – RoflcoptrException

+0

hmm ¿es posible que tenga que definir la vista de cuadrícula y la vista vacía exclusivamente (sin otros elementos de diseño como botones) en un archivo xml separado? – RoflcoptrException

+0

He modificado la respuesta con el ejemplo. Funciona bien en Android 2.1. HTH! – Karan

20

respuesta de Karan es el clavo. De hecho, AdapterView muestra la vista vacía simplemente cambiando su propia visibilidad frente a la visibilidad de la vista vacía. Sin embargo, el diseño de la vista vacía no necesariamente debe estar en el mismo archivo XML que el de AdapterView. Encontré útil separar los dos porque utilizo un único archivo XML de diseño (que contiene un GridView) para múltiples actividades, pero quería especificar diferentes diseños de EmptyView para cada uno de ellos.

La clave es agregar la vista vacía a la actividad con addContentView. Recuerde hacer esto después de ha llamado a setContentView especificando su AdapterView principal.

Mi código (en AbstractBaseActivity.onCreate):

View mainView = inflater.inflate(R.layout.imagegrid, null); 
GridView gridView = (GridView)mainView.findViewById(R.id.gridView); 
View emptyView = inflater.inflate(getIdOfEmptyView(), null, false); 
gridView.setEmptyView(emptyView); 
// Any additional processing on mainView 
setContentView(mainView); 
addContentView(emptyView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 

En cada actividad niño puedo reemplazar getIdOfEmptyView de la siguiente manera:

@Override 
protected int getIdOfEmptyView() 
{ 
    return R.layout.emptyView_Favorites; 
} 
+0

¿Qué sucede si no desea que se anule toda la actividad con su vista vacía (como encabezados o botones)? – QuinnVT

+0

Una opción podría ser ajustar tanto GridView como cualquier vista vacía que tenga en un diseño principal (como LinearLayout o RelativeLayout en la vista de la actividad). Eso asegurará que ocupen a lo sumo tanto espacio como el padre. El propio padre podría distribuirse en la vista de actividad utilizando un RelativeLayout, asegurando que los encabezados, botones, etc. se muestren correctamente independientemente de la vista GridView/vacía. – PacificSky

+1

Impresionante. Esa línea addContentView era exactamente lo que me faltaba en mi código. ¡Gracias! – Andy

2

Se pueden definir archivos de diseño XML externos, inflar y configurarlo como una vista vacía Lo único que hay que recordar es establecer el elemento primario de la vista inflada.

View emptyView = inflater.inflate(R.layout.id_of_your_layoout_file, parent, false); 
gridView.setEmptyView(emptyView); 

o

listView.setEmptyView(emptyView); 
0

respuesta de PacificSky me tiene casi a lo que necesitaba, pero la adición de la opinión de vacío a la actividad con addContentView causó la vista vacía para permanecer en el recipiente de la actividad incluso después de retirar el fragmento que contiene el ListView de la actividad. Además, la diapositiva en el menú para la actividad mostrada debajo o mezclada con la vista vacía.

La solución para mí fue la de añadir la vista vacía al contenedor pasado como un parámetro para el fragmento de onCreateView:

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    mFragmentContainer = container; 
    mListView = (ListView) mLayout.findViewById(R.id.list_view); 
    mEmptyListView = inflater.inflate(R.layout.empty_list, null, false); 
    container.addView(mEmptyListView); 
    mListView.setEmptyView(mEmptyListView); 
    mListAdapter = new MyListAdapter(getActivity(), mList); 
    mListView.setAdapter(mListAdapter); 

Y quitar la vista de vacío del recipiente en el fragmento onDestroyView:

@Override 
public void onDestroyView(){ 
    super.onDestroyView(); 
    mFragmentContainer.removeView(mEmptyListView); 
}