ClassCastException when calling ListView.addHeaderView()?

AndroidAndroid Listview

Android Problem Overview


I have a fairly complex layout (containing RelativeLayouts, TextViews and ImageViews) that I want to place above a listview. This view should scroll with the listview.

I tried adding the layout as a header to the listview using this code:

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 is a custom adapter I've written which extends BaseAdapter.

Upon executing the code, I get this error:

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)

If I comment out the mList.addHeaderView(header) line I do not get the error. I can also display the header layout without the listview with no problems.

I'm assuming this has something to do with the contents of the header layout but I'm not sure exactly what would be causing it.

Here is the header xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <RelativeLayout
            android:id="@+id/header_section"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/margin_sides"
            android:background="@color/pdp_availability_section_background" >

            <TextView
                android:id="@+id/header_text"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                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_width="fill_parent"
            android:layout_height="fill_parent"
            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_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/product_title"
                android:layout_centerHorizontal="true"
                android:layout_margin="@dimen/margin_sides" >

                <LinearLayout
                    android:id="@+id/overall_section"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:gravity="bottom" >

                    <TextView
                        android:id="@+id/overall_label"
                        style="@style/ProductTitleFont"
                        android:layout_width="wrap_content"
                        android:text="@string/overall_rating" />

                    <ImageView
                        android:id="@+id/overall_1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="10dp"
                        android:src="@drawable/icon_rating_empty" />

                    <ImageView
                        android:id="@+id/overall_2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/icon_rating_empty" />

                    <ImageView
                        android:id="@+id/overall_3"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/icon_rating_empty" />

                    <ImageView
                        android:id="@+id/overall_4"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/icon_rating_empty" />

                    <ImageView
                        android:id="@+id/overall_5"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/icon_rating_empty" />

                    <TextView
                        android:id="@+id/overall_score"
                        style="@style/ProductTitleFont"
                        android:layout_width="wrap_content"
                        android:layout_marginLeft="10dp"
                        android:text="4.6" />
                </LinearLayout>

                <Button
                    android:id="@+id/rate_review_button"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    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_width="fill_parent"
                android:layout_height="1dp"
                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_width="wrap_content"
                android:layout_below="@id/attributes_divider"
                android:layout_marginLeft="@dimen/margin_sides"
                android:text="0 " />

            <TextView
                style="@style/ProductTitleFont"
                android:layout_width="wrap_content"
                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_width="fill_parent"
                android:layout_height="1dp"
                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>

Update: I tried reducing the header .xml file to just a single TextView and the problem continues. So I don't believe the problem is being cause by something in the xml.

Android Solutions


Solution 1 - Android

FrameLayout and AbsListView convert their children layout params to FrameLayout.LayoutParams and AbsListView.LayoutParams. This is where the casting fails.

View header = View.inflate(this, R.layout.header_layout, null);

should fix it.

Edit: As mentioned in the comments, changing the ViewGroup Parameter of the inflate call also makes it work:

header = inflater.inflate(R.layout.header_layout, null, false);

Solution 2 - Android

Although Souvlaki's method will fix the issue and allow you to continue working. It is always best to give the view being inflated a reference to the container it will be in. This allows for Android to correctly inflate it for the right context.

What you should do is find the ListView and then pass that to the inflate.

ListView listView = (ListView) layout.findViewById(R.id.listview);
View header = inflater.inflate(this, R.layout.header_layout, listView, false);

Solution 3 - Android

I see same situation. in my case, it's a trouble that call timing for ListView.addHeaderView().

Before: (Error)
ListView.addHeaderView() is called in Fragment.onCreateView() method.

@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);
}


After:(OK)
ListView.addHeaderView() is called in Fragment.onActivityCreated() method.

@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);
}

Solution 4 - Android

From drspaceboo's post above, this worked for me:

@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);
	

Where getLayoutId() returns the main layout that contains the ListView xml

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhowettlView Question on Stackoverflow
Solution 1 - AndroidiCantSeeSharpView Answer on Stackoverflow
Solution 2 - AndroidCassieView Answer on Stackoverflow
Solution 3 - AndroidHogunView Answer on Stackoverflow
Solution 4 - AndroidGene BoView Answer on Stackoverflow