调用 ListView.addHeaderView() 时出现 ClassCastException?
Posted
技术标签:
【中文标题】调用 ListView.addHeaderView() 时出现 ClassCastException?【英文标题】:ClassCastException when calling ListView.addHeaderView()? 【发布时间】:2012-01-06 17:18:40 【问题描述】:我有一个相当复杂的布局(包含RelativeLayouts、TextViews 和ImageViews),我想将它放在列表视图上方。此视图应与列表视图一起滚动。
我尝试使用以下代码将布局作为标题添加到列表视图:
View v = inflater.inflate(R.layout.list_view, container, false);
View header = inflater.inflate(R.layout.header_layout, container, false);
// populate views in the header
mList = (ListView)v.findViewById(R.id.list);
mList.addHeaderView(header);
mAdapter = new ReviewsAdapter(getActivity());
mList.setAdapter(mAdapter); <-- error occurs here
ReviewsAdapter
是我编写的自定义适配器,它扩展了BaseAdapter
。
在执行代码时,我得到这个错误:
11-25 17:19:14.802: E/androidRuntime(1215): java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
11-25 17:19:14.802: E/AndroidRuntime(1215): at android.widget.ListView.clearRecycledState(ListView.java:513)
11-25 17:19:14.802: E/AndroidRuntime(1215): at android.widget.ListView.resetList(ListView.java:499)
11-25 17:19:14.802: E/AndroidRuntime(1215): at android.widget.ListView.setAdapter(ListView.java:442)
11-25 17:19:14.802: E/AndroidRuntime(1215): at com.coppi.storefront.product.ProductReviewsFragment.onCreateView(ProductReviewsFragment.java:104)
如果我注释掉 mList.addHeaderView(header)
行,我不会收到错误消息。我也可以在没有列表视图的情况下毫无问题地显示标题布局。
我假设这与标题布局的内容有关,但我不确定究竟是什么原因造成的。
这里是头xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >
<RelativeLayout
android:layout_
android:layout_ >
<RelativeLayout
android:id="@+id/header_section"
android:layout_
android:layout_
android:layout_marginBottom="@dimen/margin_sides"
android:background="@color/pdp_availability_section_background" >
<TextView
android:id="@+id/header_text"
android:layout_
android:layout_
android:layout_margin="@dimen/margin_sides"
android:paddingBottom="@dimen/margin_sides"
android:text="@string/ratings_reviews"
android:textColor="#000"
android:textSize="18dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/body_section"
android:layout_
android:layout_
android:layout_below="@id/header_section" >
<TextView
android:id="@+id/product_title"
style="@style/ProductTitleFont"
android:layout_marginBottom="@dimen/product_title_bottom_margin"
android:layout_marginLeft="@dimen/margin_sides"
android:layout_marginRight="@dimen/margin_sides" />
<RelativeLayout
android:id="@+id/attributes_section"
android:layout_
android:layout_
android:layout_below="@id/product_title"
android:layout_centerHorizontal="true"
android:layout_margin="@dimen/margin_sides" >
<LinearLayout
android:id="@+id/overall_section"
android:layout_
android:layout_
android:orientation="horizontal"
android:gravity="bottom" >
<TextView
android:id="@+id/overall_label"
style="@style/ProductTitleFont"
android:layout_
android:text="@string/overall_rating" />
<ImageView
android:id="@+id/overall_1"
android:layout_
android:layout_
android:layout_marginLeft="10dp"
android:src="@drawable/icon_rating_empty" />
<ImageView
android:id="@+id/overall_2"
android:layout_
android:layout_
android:src="@drawable/icon_rating_empty" />
<ImageView
android:id="@+id/overall_3"
android:layout_
android:layout_
android:src="@drawable/icon_rating_empty" />
<ImageView
android:id="@+id/overall_4"
android:layout_
android:layout_
android:src="@drawable/icon_rating_empty" />
<ImageView
android:id="@+id/overall_5"
android:layout_
android:layout_
android:src="@drawable/icon_rating_empty" />
<TextView
android:id="@+id/overall_score"
style="@style/ProductTitleFont"
android:layout_
android:layout_marginLeft="10dp"
android:text="4.6" />
</LinearLayout>
<Button
android:id="@+id/rate_review_button"
android:layout_
android:layout_
android:layout_below="@id/overall_section"
android:layout_marginBottom="@dimen/margin_sides"
android:layout_marginTop="@dimen/margin_sides"
android:text="@string/rate_review_button_text" />
</RelativeLayout>
<View
android:id="@+id/attributes_divider"
android:layout_
android:layout_
android:layout_below="@id/attributes_section"
android:layout_marginBottom="@dimen/margin_sides"
android:layout_marginTop="@dimen/margin_sides"
android:background="@color/pdp_section_divider" />
<TextView
android:id="@+id/review_count"
style="@style/ProductTitleFont"
android:layout_
android:layout_below="@id/attributes_divider"
android:layout_marginLeft="@dimen/margin_sides"
android:text="0 " />
<TextView
style="@style/ProductTitleFont"
android:layout_
android:layout_alignBaseline="@id/review_count"
android:layout_marginRight="@dimen/margin_sides"
android:layout_toRightOf="@id/review_count"
android:text="@string/customer_reviews" />
<View
android:id="@+id/review_count_divider"
android:layout_
android:layout_
android:layout_below="@id/review_count"
android:layout_marginBottom="@dimen/margin_sides"
android:layout_marginTop="@dimen/margin_sides"
android:background="@color/pdp_section_divider" />
</RelativeLayout>
</RelativeLayout>
更新:我尝试将标头 .xml 文件缩减为一个 TextView,但问题仍然存在。所以我不认为问题是由 xml 中的某些内容引起的。
【问题讨论】:
不应该是 mList.addHeaderView(header) 还是某处有实际的“h”视图? 感谢您发现,这是在我复制代码时发生的。更新了帖子以更准确。 【参考方案1】:FrameLayout
和 AbsListView
将其子布局参数转换为 FrameLayout.LayoutParams
和 AbsListView.LayoutParams
。这就是强制转换失败的地方。
View header = View.inflate(this, R.layout.header_layout, null);
应该修复它。
编辑: 如 cmets 中所述,更改 inflate 调用的 ViewGroup 参数也可以使其工作:
header = inflater.inflate(R.layout.header_layout, null, false);
【讨论】:
好的...但我没有使用任何 FrameLayouts。这就是为什么我很困惑。它试图投射什么? 你可以试试View header = View.inflate(this, R.layout.header_layout.null);
吗?
哦,还有:mList = (ListView) findViewById(R.id.list);
?
改成View header = View.inflate(this, R.layout.header_layout, null);
解决了!你能向我解释发生了什么吗?另外,请编辑您的答案,以便我接受。
这发生在片段的 onCreateView() 方法中。所以inflater
和container
来自方法参数。事实证明,只需将原来的 inflater.inflate(...)
调用更改为使用 null
作为 ViewGroup
参数也可以解决问题。【参考方案2】:
尽管 Souvlaki 的方法可以解决问题并让您继续工作。始终最好为正在膨胀的视图提供对其所在容器的引用。这允许 Android 为正确的上下文正确地膨胀它。
你应该做的是找到ListView
,然后将它传递给inflate。
ListView listView = (ListView) layout.findViewById(R.id.listview);
View header = inflater.inflate(this, R.layout.header_layout, listView, false);
【讨论】:
没有任何方法View.inflate
需要 4 个参数。
好点。抱歉,我应该一直用充气机打电话而不是View
为了更完整:ListView lv = (ListView) v.findViewById(android.R.id.list);
View header = (View) inflater.inflate(R.layout.header_layout, lv, false);
【参考方案3】:
我看到同样的情况。 就我而言,ListView.addHeaderView() 的调用时间很麻烦。
之前:(错误) ListView.addHeaderView() 在 Fragment.onCreateView() 方法中被调用。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View layout = inflater.inflate(R.layout.fragment_main, container, false);
mListView = (ListView) layout.findViewById(R.id.listview);
mListView.addHeaderView(inflater.inflate(R.layout.list_header_book, listview, false));
return layout;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
mAdapter = new BookAdapter(getActivity(), mBookList);
mListView.setOnItemClickListener(mBookItemClickListener);
mListView.setAdapter(mAdapter);
之后:(确定) 在 Fragment.onActivityCreated() 方法中调用 ListView.addHeaderView()。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
return inflater.inflate(R.layout.fragment_main, container, false);
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
mAdapter = new BookAdapter(getActivity(), mBookList);
mListView = (ListView) getView().findViewById(R.id.listview);
mListView.setOnItemClickListener(mBookItemClickListener);
mListView.addHeaderView(LayoutInflater.from(getActivity()).inflate(R.layout.list_header_book, null));
mListView.setAdapter(mAdapter);
【讨论】:
这是唯一对我有用的解决方案。使用onActivityCreated
。【参考方案4】:
来自drspaceboo's post above,这对我有用:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
mListLayoutView = inflater.inflate(getLayoutId(), container, false);
int headerLayoutId = R.layout.list_header_layout;
mListHeaderView = inflater.inflate(headerLayoutId, mResourcesListView, false);
// ...
mResourcesListView.addHeaderView(mListHeaderView, null, false);
其中 getLayoutId() 返回包含 ListView xml 的主布局
【讨论】:
以上是关于调用 ListView.addHeaderView() 时出现 ClassCastException?的主要内容,如果未能解决你的问题,请参考以下文章