Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException when calling ListView.addHeaderView()?

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.

like image 703
howettl Avatar asked Nov 26 '11 01:11

howettl


4 Answers

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);
like image 103
iCantSeeSharp Avatar answered Nov 03 '22 01:11

iCantSeeSharp


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);
like image 17
Cassie Avatar answered Nov 03 '22 00:11

Cassie


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);
}
like image 2
Hogun Avatar answered Nov 03 '22 01:11

Hogun


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

like image 1
Gene Bo Avatar answered Nov 03 '22 00:11

Gene Bo