2010-05-11 22 views
38

J'ai vraiment des problèmes avec la méthode setEmptyView. J'ai essayé de l'implémenter dans GridView et ListView, mais les deux ne fonctionnaient pas. Voici un échantillon codeblock:Utilisation correcte de setEmtpyView dans 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()); 

L'adaptateur réseau contient aucun élément:

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; 
     } 

    } 

J'ai aussi essayé d'appeler networkGames.setAdapter (null), mais ce travail ne marche pas non plus. Mon emtpyView ressemble à ceci:

<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> 

Je ne sais vraiment pas ce que je fais mal. J'ai également lu divers tutoriels, mais aucun d'entre eux n'a rencontré de problèmes.

Répondre

93

Vous devez ajouter cette même vue dans la présentation dans laquelle vous avez ajouté AdapterView.

AdapterView modifie uniquement sa visibilité en fonction du contenu de l'adaptateur.

ÉDITÉ:
Après la mise en page et le code fonctionne très 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>

code:

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

J'ai ajouté la disposition ci-dessus à la fin de la mise en page où je définis ma vue de grille. mais néanmoins il n'est pas affiché – RoflcoptrException

+0

hmm est-il possible que je doive définir le gridview et le emptyview exclusivement (sans autres éléments de mise en page comme des boutons) dans un fichier xml séparé? – RoflcoptrException

+0

J'ai modifié la réponse avec l'exemple. Cela fonctionne très bien sur Android 2.1. HTH! – Karan

20

réponse de Karan est sur place. L'AdapterView affiche en effet la vue vide en changeant simplement sa propre visibilité par rapport à la visibilité de la vue vide. Toutefois, la disposition de vue vide ne doit pas nécessairement être dans le même fichier XML que celui de AdapterView. J'ai trouvé utile de séparer les deux parce que j'utilise un seul fichier XML de mise en page (contenant un GridView) pour plusieurs activités, mais je voulais spécifier différentes mises en page emptyView pour chacune d'entre elles.

La clé consiste à ajouter la vue vide à l'activité avec addContentView. N'oubliez pas de le faire après vous avez appelé setContentView en spécifiant votre AdapterView principal.

Mon code (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)); 

Dans chaque activité de l'enfant que j'Override getIdOfEmptyView comme suit:

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

Que faire si vous ne voulez pas que l'activité entière soit remplacée par votre vue vide (comme les en-têtes ou les boutons)? – QuinnVT

+0

Une option peut être d'envelopper à la fois la vue GridView et la vue vide que vous avez dans une disposition parente (comme une LinearLayout ou RelativeLayout dans la vue de l'activité). Cela garantira qu'ils occupent au plus autant d'espace que le parent. Le parent lui-même peut être présenté dans la vue d'activité à l'aide d'un RelativeLayout, en s'assurant que les en-têtes, boutons, etc. sont correctement affichés indépendamment de la vue GridView/empty. – PacificSky

+1

Génial. Cette ligne addContentView était exactement ce qui me manquait dans mon code. Merci! – Andy

2

Vous pouvez définir des fichiers de mise en page XML externes, gonfler et le définir comme une vue vide. La seule chose à retenir est de définir le parent de la vue gonflée.

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

ou

listView.setEmptyView(emptyView); 
0

réponse de PacificSky m'a fait presque ce que je avais besoin, mais en ajoutant le point de vue vide à l'activité avec addContentView a causé la vue vide de rester dans le conteneur de l'activité même après le retrait du fragment contenant le ListView de l'activité. En outre, la diapositive dans le menu pour l'activité affichée sous ou mélangé avec la vue vide.

La solution pour moi était d'ajouter la vue vide au conteneur passé en paramètre à onCreateView de fragment:

@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); 

et retirez la vue vide du récipient dans onDestroyView de fragment:

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