Android:在向ExpandableListView添加标题视图时出现ClassCastException

43

我正在尝试添加一个标题到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))时,但我无法弄清楚为什么。有任何想法吗?

4个回答

90

好的,我解决了这个问题。我通过将视图的LayoutParams程序化地设置为ListView的LayoutParams来消除了运行时错误,就像这样:

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

在添加视图之前,你需要设置视图的LayoutParams。这是因为Android文档中提到:

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

文档中指出:

这些参数提供给此视图的父类,指定它应该如何排列。有许多 ViewGroup.LayoutParams 的子类,这些子类与负责排列其子项的不同 ViewGroup 子类相对应。

所以基本上,如果你要将一个视图添加到另一个视图中,则必须将该视图的LayoutParams设置为父视图使用的LayoutParams类型,否则将会出现运行时错误。


3
我花了最后两个小时来尝试理解这个问题。谢谢! - Tenfour04
1
感谢您在这里发布答案,非常有帮助! - AndersG
2
感谢您花时间解释这个问题,其他地方都没有一个很好的答案。 - Tyler
谢谢你的解释。 - yajnesh

5
尽管上面的答案对很多人来说可能有效,但仍有更好的解释。 在调用listview.addHeaderViewlistview.addFooterView后,ClassCastException是正常行为。
原因是初始适配器被包装在HeaderViewListAdapter中。要获取您的适配器,请使用此代码。
YourAdapter ya = (YourAdapter) ((HeaderViewListAdapter)lv.getAdapter()).getWrappedAdapter();

这里的代码来自于这里


你的解决方案比Christopher的解决方案更有效。所以如果Christopher的解决方案不起作用,试试这个吧! - Jordi Sipkens

1
在我的情况下,这种方法不起作用。在设置适配器之前,我必须为我的listView设置一个footerView。首先,在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);

Where

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

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

0

你应该将父视图放到你的充气视图中。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接