web-dev-qa-db-fra.com

setEmptyView sur ListView ne montrant pas sa vue dans une application Android?

J'ai un problème avec la méthode setEmptyView à partir d'un ListView. 

Voici mon code Java:

ListView view = (ListView)findViewById(R.id.listView1);
view.setEmptyView(findViewById(R.layout.empty_list_item));

ArrayAdapter<Session> adapter1 = new ArrayAdapter<Session>(this, Android.R.layout.simple_list_item_1, 
        Android.R.id.text1, MainController.getInstanz().getItems());
view.setAdapter(adapter1);

empty_list_item:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:text="@string/emptyList" >

</TextView>

listview:

<ListView
        Android:id="@+id/listView1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" >

Quel est le problème avec mon code? Quand j'ai des objets, je les vois dans la liste. Mais lorsque la liste est vide, je ne vois pas la TextView.

44
gurehbgui

le problème est, je dois faire un addContentView:

View empty = getLayoutInflater().inflate(R.layout.empty_list_item, null, false);
addContentView(empty, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.setEmptyView(empty);

maintenant c'est bien

31
gurehbgui

Votre TextView doit être placé juste sous l'élément ListView avec sa visibilité définie (Android: accessibility = "gone"), ne le placez pas dans un autre modèle .

<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="@+id/listViewFangbuch"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" >
    </ListView>
    <TextView
        Android:id="@+id/empty_list_item"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:visibility="gone"
        Android:text="@string/emptyList" >
    </TextView>

</LinearLayout>

Et voici à quoi votre code pourrait ressembler

ListView view = (ListView)findViewById(R.id.listViewFangbuch);
view.setEmptyView(findViewById(R.id.empty_list_item));

ArrayAdapter<Session> adapter1 = new ArrayAdapter<Session>(this, Android.R.layout.simple_list_item_1, 
        Android.R.id.text1, MainController.getInstanz().getItems());
view.setAdapter(adapter1);
99
mmbrian

Pour moi, aucune de ces réponses n'a fonctionné pour moi. Ce que je devais faire était d’ajouter manuellement (gonflé) la vue vide à la vue "parent" de la vue en liste:

ListView my_list = (ListView) findViewById(R.id.my_list);
View emptyView = getLayoutInflater().inflate(R.layout.empty_view,null);
((ViewGroup)my_list.getParent()).addView(emptyView); 
listView.setEmptyView(emptyView);
30
danigonlinea

Le moyen le plus simple d'utiliser setEmptyView() consiste à placer votre TextView "vide" et votre ListView dans le même modèle, comme suit:

<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="@+id/listView1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    <TextView
        Android:id="@+id/empty_list_item"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:text="@string/emptyList"
        Android:visibility="gone" />

</LinearLayout>

Maintenant vous pouvez utiliser:

view.setEmptyView(findViewById(R.id.empty_list_item));
18
Sam

Après avoir essayé toutes les solutions présentées ici et expérimenté, je pense que le code ci-dessous est la meilleure méthode à utiliser lorsque votre ListView et votre Vue vide ne sont pas côte à côte dans une présentation avec les identifiants automatiques définis.

ViewGroup parentGroup = (ViewGroup)getListView().getParent();
View empty = getActivity().getLayoutInflater().inflate(R.layout.list_empty_view,
                                                       parentGroup,
                                                       false);
parentGroup.addView(empty);
getListView().setEmptyView(empty);

Raisonnement:

  • En passant le groupe parent à gonfler, les attributs layout_ * de votre layout de vue vide sont respectés
  • En n'attachant pas la vue dans inflate (le paramètre false), la vue vide est renvoyée. Sinon, inflate renverrait le parent nous obligeant à utiliser parentGroup.findViewById (empty_view_id) pour obtenir la vue vide à utiliser avec setEmptyView (). Ici, nous évitons la recherche supplémentaire, le besoin d'un autre identifiant et le besoin d'exposer cet identifiant dans notre code. Si nous n’avions pas besoin de conserver la référence vide, il serait correct de demander à inflate de s’attacher en supprimant le besoin de l’appel addView.
  • Un anti-motif, addContentView (), n’est pas la bonne approche. Il apparaîtra équivalent tant que votre ListView occupe tout l'espace visible de votre activité. Au lieu que votre vue vide soit un frère de votre liste, elle finit par être un frère de vos autres mises en page de niveau racine dans votre activité. Cela semble fonctionner car il est flottant (ordre z) par-dessus toutes les autres vues de l'activité. Voir: Activity.addContentView (View) == ViewGroup.addContentView (View)?
13
Harvey

Le problème réside principalement dans le fait que la classe AdapterView n'ajoute pas la vue que vous transmettez à setEmptyView () à un conteneur. Cela change juste la visibilité. Il existe de nombreuses façons de placer votre objet "vue vide" dans un conteneur, comme décrit dans les autres réponses.

La documentation pour AdapterView devrait vraiment être mise à jour pour refléter cela, car cela n’est pas évident.

6
Dave

Créez une présentation en XML spécifiant à la fois la variable ListView et la vue vide que vous souhaitez utiliser. Si vous leur donnez les identifiants @Android:id/list et @Android:id/empty, Android utilisera automatiquement la vue avec id:empty lorsque la liste est vide.

4
ItsNotAboutTheName

Il existe des solutions correctes, mais je pense que c'est la meilleure approche!

View emptyView = getLayoutInflater().inflate(R.layout.empty_list_cart, null);
addContentView(emptyView, listView.getLayoutParams()); // You're using the same params as listView
listView.setEmptyView(emptyView);
listView.setAdapter(adapter);
3
cesards

Juste utiliser, 

View emptyView = getLayoutInflater().inflate(R.layout.empty_view, null);
((ViewGroup)listView.getParent()).addView(emptyView);

Au lieu de listView.setEmptyView(emptyView);

1
Sazzad Hissain Khan

ces deux méthodes m'ont également aidé à afficher une vue vide:

    adapter.notifyDataSetChanged();
    list.invalidateViews();
1
user2162746

Je viens juste d'apprendre Android, mais l'extrait de https://developer.Android.com/guide/topics/ui/layout/listview.html Décrit une approche différente:

// Create a progress bar to display while the list loads
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT, Gravity.CENTER));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
// Must add the progress bar to the root of the layout
ViewGroup root = (ViewGroup) findViewById(Android.R.id.content);
root.addView(progressBar); 

ViewGroup root = (ViewGroup) findViewById (Android.R.id.content);

0
Yurii Solopov

Mon problème était que j'ai ajouté une vue de pied de page qui semble ne pas fonctionner avec la vue vide . Après la suppression de la vue de pied de page, la vue vide est affichée.

0
Stefan