Android: ClassCastException al agregar una vista de encabezado a ExpandableListView
-
10-10-2019 - |
Pregunta
Estoy intentando añadir una cabecera a un ExpandableListView este modo:
headerView = View.inflate(this, R.layout.header, null);
expandableListView.addHeaderView(headerView);
expandableListView.setAdapter(new SectionedAdapter(this));
Lo que me da el siguiente error:
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)
Esto está ocurriendo en la llamada a expandableListView.setAdapter(new SectionedAdapter(this))
, pero no puedo entender por qué. Algunas ideas?
Solución
Ok, pensé éste hacia fuera. Me libré del error de ejecución mediante el establecimiento mediante programación LayoutParams de la vista a ListView LayoutParams, así:
headerView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.FILL_PARENT, ListView.LayoutParams.WRAP_CONTENT));
antes de añadir la vista. El ser razón se encuentra en la documentación de Android:
que establece que:
Estos parámetros de suministro a la padres de este punto de vista que especifica cómo debe ser arreglado. Hay muchos subclases de ViewGroup.LayoutParams, y estos corresponden a los diferentes subclases de ViewGroup que son responsable de organizar su los niños.
Así que, básicamente, si va a agregar una vista a otra, debe establecer el LayoutParams de la vista con el tipo LayoutParams que los usos de los padres, o se obtendrá un error de ejecución.
Otros consejos
A pesar de que la respuesta anterior podría funcionar para muchos, todavía hay una mejor explicación.
ClassCastException
es el comportamiento normal después de llamar listview.addHeaderView
o listview.addFooterView
.
La razón es que el adaptador inicial se envuelve en el HeaderViewListAdapter
.
Para obtener su adaptador de utilizar este código.
YourAdapter ya = (YourAdapter) ((HeaderViewListAdapter)lv.getAdapter()).getWrappedAdapter();
En mi caso esto no funcionó. Tenía que establecer un footerView a mi ListView antes de colocarlo de adaptador. En primer lugar me inicializa mi loadingView de un archivo de diseño en el método OnCreate:
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
loadingView = layoutInflater.inflate(R.layout.loading_view, null);
Luego usé esta solución en el mismo método:
this.setIsLoading(true);
listView.setAdapter(adapter);
this.setIsLoading(false);
Donde
private void setIsLoading(boolean isLoading)
{
this.isLoading = isLoading;
if (isLoading) {
listView.addFooterView(loadingView);
}
else {
listView.removeFooterView(loadingView);
}
}
Se debe poner vista padre a su visión exagerada.
ListView listview = (ListView) findViewById(R.id.listview);
headerView = View.inflate(this, R.layout.header, listview, false); // set listview as parent view
listview.addHeaderView(headerview);