Android: ClassCastException al agregar una vista de encabezado a ExpandableListView
android-linearlayout (4)
Estoy tratando de agregar un encabezado a una ExpandableListView así:
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á sucediendo en la llamada a expandableListView.setAdapter(new SectionedAdapter(this))
, pero no puedo entender por qué. ¿Algunas ideas?
Aunque la respuesta anterior podría funcionar para muchos, todavía hay una mejor explicación. ClassCastException
es el comportamiento normal después de llamar a listview.addHeaderView
o listview.addFooterView
.
La razón es que el adaptador inicial está HeaderViewListAdapter
en HeaderViewListAdapter
. Para obtener su adaptador use este código.
YourAdapter ya = (YourAdapter) ((HeaderViewListAdapter)lv.getAdapter()).getWrappedAdapter();
Código tomado de aquí
Debería poner la vista principal en su vista inflada.
ListView listview = (ListView) findViewById(R.id.listview);
headerView = View.inflate(this, R.layout.header, listview, false); // set listview as parent view
listview.addHeaderView(headerview);
En mi caso, esto no funcionó. Tuve que configurar footerView en mi lista de lista antes de configurar su adaptador. Primero, inicié mi vista de carga desde 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);
Dónde
private void setIsLoading(boolean isLoading)
{
this.isLoading = isLoading;
if (isLoading) {
listView.addFooterView(loadingView);
}
else {
listView.removeFooterView(loadingView);
}
}
Ok, me di cuenta de esto. Me deshice del error de tiempo de ejecución programando programáticamente los LayoutParams de View a ListView LayoutParams, así:
headerView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.FILL_PARENT, ListView.LayoutParams.WRAP_CONTENT));
antes de agregar la vista. La razón es que se encuentra en los documentos de Android:
el cual establece que:
Estos proporcionan parámetros al padre de esta vista que especifica cómo se debe organizar. Hay muchas subclases de ViewGroup.LayoutParams, y estas corresponden a las diferentes subclases de ViewGroup que son responsables de organizar sus hijos.
Así que, básicamente, si agrega una vista a otra, DEBE establecer los Parámetros de diseño de la vista en el tipo de LayoutParams que usa el padre, o obtendrá un error de tiempo de ejecución.