Android - ClassCastException - on LayoutParams from LinearLayout to AbsListView
Asked Answered
M

5

17

I have a list adaptor that i'm trying to set a custom xml for (item.xml) if i dont use inflation (direct identifying the textview through an application context), it works perfectly.. but then my listview can't be themed..

public View getView(int position, View convertView, ViewGroup parent) {
        //System.gc();
        TextView tv;

        LayoutInflater inflater = getLayoutInflater();

        View row = View.inflate(mContext,R.layout.item,null); //.inflate(R.layout.item, parent, false); doesnt work either..
        String id = null;
        if (convertView == null) {
            tv =  (TextView) row.findViewById(R.id.TextView01);;
        } else
            tv = (TextView) convertView;

[..]

in logcat I am getting this..

    07-15 19:45:51.710: ERROR/AndroidRuntime(20185): FATAL EXCEPTION: main
        java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
        at android.widget.ListView.setupChild(ListView.java:1827)
        at android.widget.ListView.makeAndAddView(ListView.java:1794)
        at android.widget.ListView.fillDown(ListView.java:688)

my item.xml file is as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_height="wrap_content"
          android:gravity="left|center"
          android:layout_width="fill_parent"
          android:paddingBottom="15px"
          android:background="#fff200"
          android:paddingTop="15px"
          android:paddingLeft="15px">

<TextView android:id="@+id/TextView01"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:textSize="40px"
          android:textStyle="bold"
          android:layout_marginLeft="20px"
          android:textColor="#0099CC">
</TextView>
</LinearLayout>
Maw answered 15/7, 2012 at 14:23 Comment(1)
can any one help #30952108Danaus
W
36

The problem is caused by wrapping the control you're returning from the adapter in a linearlayout. Lose the LinearLayout from your layout file (just put the TextView as the root) and I think it should work.

To expand slighly: you're creating your control, and then adding it into a LinearLayout. At this point a LinearLayout$LayoutParams object is allocated for it and set as its layout params. You then pull it out of the linear layout and put it into your list view, which doesn't understand the LinearLayout$LayoutParams.

Alternatively, return row from getView rather than (as I presume you are doing at the moment, as you have cut the return line out of your quoted code) returning tv.

(Another, unrelated hint: you are inflating your layout and then discarding it when convertView != null; this will result in poor scrolling performance on slow devices. Only perform the inflation if you're actually going to need it.)

Weeping answered 15/7, 2012 at 16:20 Comment(5)
yes! it worked.. but as you said, the scrolling is kinda jerky.. how do i smoothen it out without doing inflation? as in how do i get a custom layout for the list without inflating it? and i didnt understand the discarding part.. how is it getting discarded? the uri source of this list is from the mediastore..Maw
Thank you for this @Weeping , it helped understanding the issue! Another thing you can do if you still want to use the tv object is to set its layout params to be an instance of AbsListView.LayoutParams, ie: tv.setLayoutParams(new AbsListView.LayoutParams(width, height);Sol
"Alternatively, return row from getView rather than (as I presume you are doing at the moment, as you have cut the return line out of your quoted code) returning tv." That worked like a charm.Thanks.Grof
This answer is misleading. The OP is probably returning tv and not row. If the OP changed the method to return the row then the class cast exception would not occur. There is no reason not wrap the row's TextView in a LinearLayout if that is what you intend.Mir
@Mir -- indeed, which is why my answer contains the suggestion "Alternatively, return row from getView rather than ... returning tv". On the other hand, for the application OP had, the LinearLayout is unnecessary, and therefore it would be better not to have to create one for every list view item his app shows.Weeping
P
20

you probably are returning the tv instead of row

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv;

    LayoutInflater inflater = getLayoutInflater();
    View row = View.inflate(mContext,R.layout.item,null);
    String id = null;
    if (convertView == null) {
        tv =  (TextView) row.findViewById(R.id.TextView01);;
    } else
        tv = (TextView) convertView;
    }
 return row;  // returning tv brings to ClassCast!
Pep answered 9/9, 2012 at 11:58 Comment(0)
F
5

Did you try to use the layout inflater to inflate the static xml layout? Like this:

LayoutInflater li = LayoutInflater.from(context);
View rootView = li.inflate(R.layout.item, null);
Florentinaflorentine answered 15/7, 2012 at 14:38 Comment(0)
M
0

A proper way to work with ArrayAdapter's getView for your code is this:

public View getView(int position, View convertView, ViewGroup parent) {
    //System.gc(); // Should not manually call gc
    View row;
    LayoutInflater inflater = getLayoutInflater();
    if (convertView == null) {
        row = inflater.inflate(R.layout.item, parent, false);
    } else
        row = convertView;

    TextView tv = (TextView) row.findViewById(R.id.TextView01);

Also, do not manually garbage collect in your code if possible.

Mannose answered 15/7, 2012 at 14:34 Comment(1)
nope, still getting the same error. if i put tv = new TextView(mContext.getApplicationContext()); in the if statement, only then it is working but not rendering my required xml file..Maw
O
0

I had the same problem and i used these codes :

public View getView(final int position, View convertView, ViewGroup parent) {
    convertView = G.layoutInflater.inflate(R.layout.list_lay_cities_markets, null);

    // your work 

    notifyDataSetChanged();
    return convertView;
}
Overindulge answered 21/5, 2017 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.