ClassCastException when calling ListView.addHeaderView()? - android

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.

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

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

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

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

Related

ListFragment with custom layout doesn't populate empty list notifier

I have created a custom layout for ListFragment, using ArrayAdapter, but when the array is empty, no empty message is displayed. I get no errors on the console. My min SDK version is 15, there should be no need to use support libraries.
headline_list.xml (i.e. my custom layout file)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#id/android:list" />
<TextView android:id="#+id/my_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
HeadlineFragment.java
public class HeadlineFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.headline_list, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<String> headlines = ...; // populate headlines list
setListAdapter(new ArrayAdapter<String>(getActivity(),
R.layout.headline_list, R.id.my_text, headlines));
}
}
You are getting suggestions here, you should do the tries.. Anyway this layout is working perfectly for me:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, from);
setListAdapter(adapter);
return rootView;
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmet"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView
android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
</RelativeLayout>
I had simply forgot to set the text!
After setting it, my TextView is displayed correctly:
<TextView android:id="#id/android:empty"
android:textSize="16sp"
android:textStyle="bold"
android:text="#string/empty_text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
with string resource in strings.xml file:
<string name="empty_text">There are no data</string>
Unfortunately, the TextView is also displayed in each row of the list, but this is another question.
It may be related to the linear layout and the fact you didn't specified weight attribute to each of the items, so one may overlay another. Check your layout params and this:
Showing empty view when ListView is empty

My findViewById() returns null, but it shouldn't

My findViewById returns null, but it shouldn't.
As you'll see, the button is in the same XML file.
And calling getActivity() makes no difference at all
Here's my onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
Button request = (Button) getView().findViewById(R.id.button_request);
return rootView;
}
And here's my fragment_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container_relative"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
tools:context="br.com.igor.MainActivity$PlaceholderFragment" >
<TextView
android:id="#+id/servic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:layout_marginBottom="0dp"
android:paddingTop="15dp"
android:text="Sample instructions" />
<Button
android:id="#+id/button_request"
style="#style/button_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:layout_below="#id/servic"
android:text="Request" />
</RelativeLayout>
getView is returning null, not findViewById. Use rootView in place of getView
Button request = (Button) rootView.findViewById(R.id.button_request);
getView returns the view you inflated in onCreateView

Multiple Custom ListFragment in view pager

I have a viewPager that include 3 different fragments with associated layouts (fragment_new_quiz, fragment_completed_quiz, fragment_created_quiz. Each one implements the onCreateView similarly like:
public class NewQuizFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_new_quiz, container, false);
mListView = (ListView) getActivity().findViewById(R.id.list);
mArrayAdapter = new QuizAdapter(mItemList, getActivity());
mArrayAdapter.setNotifyOnChange(true);
setListAdapter(mArrayAdapter);
return rootView;
}
}
The layouts should all be different so I cannot reuse them. They are defined similarly to:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fa6a6a"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/createButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create" />
<TextView
android:id="#+id/intro_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_weight="1"
android:text="Created Quiz"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="299dp" >
<ListView
android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" />
<TextView
android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No items."
android:textAppearance="?android:attr/textAppearanceMedium" />
</FrameLayout>
</LinearLayout>
The problem I face is with this code configuration, eclipse gives me the error:
list cannot be resolved or is not a field
related to this line
mListView = (ListView) getActivity().findViewById(R.id.list);
If however I change any of the 3 listview ids to something else in any of the 3 fragments, I don't get the compile time error. However, when I run the code, I get the following error:
11-16 16:32:52.533: E/AndroidRuntime(20935):
java.lang.RuntimeException: Your content must have a ListView whose id
attribute is 'android.R.id.list'.
I am kind of clueless about what to do. Is my usage of the various components not appropriate?
In your XML, change these
android:id="#+id/android:list"
android:id="#+id/android:empty"
to these:
android:id="#android:id/list"
android:id="#android:id/empty"
In your Fragments, change
mListView = (ListView) getActivity().findViewById(R.id.list);
to
mListView = (ListView) rootView.findViewById(android.R.id.list);
These are the proper ways to reference resource ids declared in the android namespace.

I do not see the items in the gridview android

I have a GridView in which I put a horizontal scroll. When it was all vertical scroll was working perfectly, now I have changed the type of gridview to make it horizontal but you no longer see the items in the gridview.
in xml:
<com.jess.ui.TwoWayGridView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/dashboard_grid_report"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#E8E8E8"
app:gravity="center"
app:horizontalSpacing="0dp"
app:scrollDirectionLandscape="horizontal"
app:scrollDirectionPortrait="horizontal"
app:stretchMode="none"
app:verticalSpacing="0dp" />
xml of item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_prospect"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#00BFFF" >
<TextView
android:id="#+id/TxtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:textColor="#android:color/black" />
</RelativeLayout>
In file java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_dashboard,
container, false);
TwoWayGridView gridViewReport = (TwoWayGridView) rootView.findViewById(R.id.dashboard_grid_report);
GridClientAdapter customGridClientAdapter = new GridClientAdapter(getActivity().getApplicationContext(), R.layout.item_client, Costant.listReport);
gridViewReport.setAdapter(customGridClientAdapter);
//......
return rootView;
}
when it was a usual gridview and vertical scroll was everything worked, asesso no longer works. Who can explain it to me?
In xml remove
app:stretchMode="none"
it works

view.findViewById returns null for ImageView but not ListView

When using view.findViewById(id) in my fragment to find the ListView, this returns fine and I can use the value, however, when I try to find the ImageView using the exact same method but just changing the ID to the correct one, it will return null, which causes problems later in the application.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_boardlist,
container, false);
boardListView = (ListView) fragmentView
.findViewById(R.id.fragmentListView);
stickyImageView = (ImageView) fragmentView
.findViewById(R.id.favouriteImageView);
// ...
return fragmentView;
}
Not sure why this is happening as I am using the same way so I was wondering if anyone else knew why.
Here is the XML:
<TextView
android:id="#+id/initialsTextView"
android:layout_width="35dp"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:textSize="12sp" />
<TextView
android:id="#+id/fullNameTextView"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_weight=".85"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ImageView
android:id="#+id/favouriteImageView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight=".15"
android:clickable="true"
android:contentDescription="#string/imageview_contentdescription"
android:src="#android:drawable/star_big_off" />
Correct me if I am wrong, but if you are trying to access an ImageView that is part of the custom row of the ListView, first you need to set the adapter. Then you need to override the getView() from the Adapter. Then get a reference of the ImageView.

Categories

Resources