Domanda Android: ClassCastException quando si aggiunge una vista di intestazione a ExpandableListView


Sto cercando di aggiungere un'intestazione a un ExpandableListView in questo modo:

headerView = View.inflate(this, R.layout.header, null);
expandableListView.addHeaderView(headerView);
expandableListView.setAdapter(new SectionedAdapter(this));

Il che mi dà il seguente errore:

 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)

Questo sta accadendo alla chiamata a expandableListView.setAdapter(new SectionedAdapter(this))ma non riesco a capire perché. Qualche idea?


44
2017-12-09 00:33


origine


risposte:


Ok, ho capito questo. Mi sono sbarazzato dell'errore di runtime impostando in modo programmatico i layout della vista su ListView LayoutParams, in questo modo:

headerView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.FILL_PARENT, ListView.LayoutParams.WRAP_CONTENT));

prima di aggiungere la vista. La ragione è trovata nei documenti Android:

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

che afferma che:

Questi parametri di fornitura al    genitore di questa vista specificando come dovrebbe essere organizzato. Ci sono molti   sottoclassi di ViewGroup.LayoutParams,   e questi corrispondono al diverso   sottoclassi di ViewGroup che sono   responsabile per organizzare il loro   bambini.

Quindi, in pratica, se stai aggiungendo una vista a un'altra, DEVI impostare i LayoutParam della vista sul tipo di layoutParams che utilizza il genitore, o otterrai un errore di runtime.


91
2017-12-09 17:43



Anche se la risposta di cui sopra potrebbe funzionare per molti, c'è ancora una spiegazione migliore. ClassCastException è il comportamento normale dopo aver chiamato listview.addHeaderView o listview.addFooterView.

Il motivo è che l'adattatore iniziale è avvolto nel HeaderViewListAdapter. Per ottenere il tuo adattatore usa questo codice.

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

Codice preso da qui


4
2017-11-03 18:20



Nel mio caso questo non ha funzionato. Ho dovuto impostare un footerView per il mio listView prima di impostare il suo adattatore. Per prima cosa ho inizializzato il mio loadingView da un file di layout nel metodo OnCreate:

LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
loadingView = layoutInflater.inflate(R.layout.loading_view, null);

Quindi ho usato questa soluzione alternativa nello stesso metodo:

this.setIsLoading(true);
listView.setAdapter(adapter);
this.setIsLoading(false);

Dove

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

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

1
2017-11-28 17:39



Dovresti mettere la vista genitore alla tua vista gonfiata.

ListView listview = (ListView) findViewById(R.id.listview);
headerView = View.inflate(this, R.layout.header, listview, false); // set listview as parent view
listview.addHeaderView(headerview);

0
2018-03-16 01:56