web-dev-qa-db-ja.com

Android:ヘッダービューをExpandableListViewに追加するとClassCastExceptionが発生する

私は次のようにExpandableListViewにヘッダーを追加しようとしています:

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

これは私に次のエラーを与えます:

_ 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)
_

これはexpandableListView.setAdapter(new SectionedAdapter(this))の呼び出しで発生していますが、理由がわかりません。何か案は?

44

わかりました、これはわかりました。次のように、プログラムでビューのLayoutParamsをListView LayoutParamsに設定することで、実行時エラーを取り除きました。

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

ビューを追加する前。理由はAndroid docs:

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

これは次のように述べています:

これらは、このビューのparentにパラメーターを提供して、配置方法を指定します。 ViewGroup.LayoutParamsには多くのサブクラスがあり、これらは、子の配置を担当するViewGroupのさまざまなサブクラスに対応しています。

したがって、基本的には、ビューを別のビューに追加する場合、ビューのLayoutParamsを親が使用するLayoutParamsタイプに設定する必要があります。そうしないと、ランタイムエラーが発生します。

91

上記の答えは多くの人にとってうまくいくかもしれませんが、まだより良い説明があります。 ClassCastExceptionは、listview.addHeaderViewまたはlistview.addFooterViewを呼び出した後の通常の動作です。

その理由は、最初のアダプターがHeaderViewListAdapterでラップされているためです。アダプターを取得するには、このコードを使用します。

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

ここから取得したコード

4
Adeel Ahmad

私の場合、これはうまくいきませんでした。アダプターを設定する前に、フッタービューをリストビューに設定する必要がありました。まず、OnCreateメソッドでレイアウトファイルからloadingViewを初期化しました。

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

次に、この回避策を同じ方法で使用しました。

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

どこ

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

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

親ビューを膨張ビューに配置する必要があります。

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
Cheng