44

Estoy intentando añadir una cabecera a un ExpandableListView así:Android: ClassCastException al agregar una vista de encabezado a ExpandableListView

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) 

Este es sucediendo en la llamada al expandableListView.setAdapter(new SectionedAdapter(this)), pero no puedo entender por qué. ¿Algunas ideas?

Respuesta

91

Ok, me figuré esto. 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:

http://developer.android.com/reference/android/view/View.html#setLayoutParams(android.view.ViewGroup.LayoutParams)

que establece que:

These supply parameters to the parent of this view specifying how it should be arranged. There are many subclasses of ViewGroup.LayoutParams, and these correspond to the different subclasses of ViewGroup that are responsible for arranging their children.

Así que, básicamente, si va a agregar una vista a otra, debe establecer el LayoutParams de la vista al tipo de LayoutParams que utiliza el padre, o obtendrá un error de tiempo de ejecución.

+3

Pasé las últimas dos horas tratando de resolver esto. ¡Gracias! – Tenfour04

+1

Gracias por publicar la respuesta aquí, ¡muy útil! – AndersG

+0

¡Qué mensaje de error tan tonto ... Gracias por ahorrar tiempo! – SuitUp

1

En mi caso esto no funcionó. Tuve que configurar footerView en mi lista de lista antes de configurar su 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); 

Dónde

private void setIsLoading(boolean isLoading) 
{ 
    this.isLoading = isLoading; 

    if (isLoading) { 
     listView.addFooterView(loadingView); 
    } 
    else { 
     listView.removeFooterView(loadingView); 
    } 
} 
4

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 al listview.addHeaderView o listview.addFooterView.

La razón es que el adaptador inicial está envuelto en el HeaderViewListAdapter. Para obtener su adaptador use este código.

YourAdapter ya = (YourAdapter) ((HeaderViewListAdapter)lv.getAdapter()).getWrappedAdapter(); 

Code taken from here

+0

Tu solución funcionó con la solución de Christopher. Entonces, si la solución de Christopher no funciona, ¡prueba con estos tipos! –

0

Usted 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); 
Cuestiones relacionadas