调用 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】:

FrameLayoutAbsListView 将其子布局参数转换为 FrameLayout.LayoutParamsAbsListView.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() 方法中。所以inflatercontainer 来自方法参数。事实证明,只需将原来的 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?的主要内容,如果未能解决你的问题,请参考以下文章

ListView的 addHeaderView

ListView addHeaderView

ListView 添加 HeaderView常见错误

求助,如何在listview里addheadview-Android开发问答

Android ListView添加头部和尾部

如何将ListView标题放入Android泡泡中