Android: ClassCastException lors de l'ajout d'une vue d'en-tête ExpandableListView
-
10-10-2019 - |
Question
Je suis en train d'ajouter un en-tête à un ExpandableListView comme ceci:
headerView = View.inflate(this, R.layout.header, null);
expandableListView.addHeaderView(headerView);
expandableListView.setAdapter(new SectionedAdapter(this));
Ce qui me donne l'erreur suivante:
12-08 16:23:42.354:
ERROR/AndroidRuntime(421): Caused by:java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams
12-08 16:23:42.354: ERROR/AndroidRuntime(421): at android.widget.ListView.clearRecycledState(ListView.java:504)
12-08 16:23:42.354: ERROR/AndroidRuntime(421): at android.widget.ListView.resetList(ListView.java:490)
12-08 16:23:42.354:ERROR/AndroidRuntime(421):at android.widget.ListView.setAdapter(ListView.java:422)
12-08 16:23:42.354:ERROR/AndroidRuntime(421): at android.widget.ExpandableListView.setAdapter(ExpandableListView.java:475)
Ce qui se passe à l'appel à expandableListView.setAdapter(new SectionedAdapter(this))
, mais je ne peux pas comprendre pourquoi. Toutes les idées?
La solution
Ok, je me suis dit celui-ci dehors. Je me suis débarrassé de l'erreur d'exécution en mettant à programatically ListView LayoutParams les LayoutParams de la vue, comme ceci:
headerView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.FILL_PARENT, ListView.LayoutParams.WRAP_CONTENT));
avant d'ajouter la vue. La raison se trouve dans la documentation Android:
qui stipule que:
Ces paramètres d'alimentation à la parent de ce point de vue en précisant la façon dont il devrait être organisé. Il y a beaucoup de sous-classes de ViewGroup.LayoutParams, et ceux-ci correspondent aux différents sous-classes de ViewGroup qui sont responsable de l'organisation de leur enfants.
Donc, fondamentalement, si vous ajoutez une vue à l'autre, vous devez définir les LayoutParams de la vue du type LayoutParams que les utilisations des parents, ou vous obtiendrez une erreur d'exécution.
Autres conseils
Même si la réponse ci-dessus pourrait fonctionner pour beaucoup, il y a encore une meilleure explication.
ClassCastException
est le comportement normal après avoir appelé listview.addHeaderView
ou listview.addFooterView
.
La raison en est que l'adaptateur initial est enveloppé dans la HeaderViewListAdapter
.
Pour obtenir votre carte utilisez ce code.
YourAdapter ya = (YourAdapter) ((HeaderViewListAdapter)lv.getAdapter()).getWrappedAdapter();
Dans mon cas, cela ne fonctionne pas. Je devais mettre un footerView à mon listView avant de l'adaptateur de lui. D'abord, j'initialisés mon loadingView à partir d'un fichier de mise en page dans la méthode OnCreate:
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
loadingView = layoutInflater.inflate(R.layout.loading_view, null);
Alors je cette solution de contournement dans la même méthode:
this.setIsLoading(true);
listView.setAdapter(adapter);
this.setIsLoading(false);
Où
private void setIsLoading(boolean isLoading)
{
this.isLoading = isLoading;
if (isLoading) {
listView.addFooterView(loadingView);
}
else {
listView.removeFooterView(loadingView);
}
}
Vous devriez mettre vue parent à votre vue gonflé.
ListView listview = (ListView) findViewById(R.id.listview);
headerView = View.inflate(this, R.layout.header, listview, false); // set listview as parent view
listview.addHeaderView(headerview);