Search code examples
androidandroid-layoutlistviewandroid-listviewandroid-cursoradapter

ListView requestLayout() warning


I have a ListView and which contains Items made of a RelativeLayout:

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

    <ListView
        android:id="@+id/ListView01"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_alignParentLeft="false"
        android:layout_alignParentTop="true"
        android:fastScrollEnabled="true"
        android:fastScrollAlwaysVisible="true"
        android:smoothScrollbar="false"
        android:scrollingCache="true" />

</RelativeLayout>

The Items:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingTop="8dp"
    android:paddingBottom="8dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Erika Mustermann"
        android:id="@+id/textViewName"
        android:layout_marginLeft="8dp"
        android:layout_marginBottom="-3dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Company Inc."
        android:id="@+id/textViewCompany"
        android:layout_marginLeft="24dp"
        android:textColor="#6b6b6b"
        android:textSize="13dp"
        android:visibility="gone" />

    <RelativeLayout android:id="@+id/RelativeLayout01"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">

        <LinearLayout
            android:id="@+id/linearLayout_one"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="24dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="Work: "
                android:id="@+id/NumLabel0"
                android:textColor="#6b6b6b" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="+49-1234-1234567"
                android:id="@+id/textViewPhoneWork"
                android:textColor="#6b6b6b" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/linearLayout_two"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="24dp"
            android:layout_below="@+id/linearLayout_one">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="Mobile: "
                android:id="@+id/NumLabel1"
                android:textColor="#6b6b6b" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="+49-1234-1234567"
                android:id="@+id/textViewPhoneMobile"
                android:textColor="#6b6b6b" />
        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

The ListView gets a CursorAdapter which with a ViewHolder pattern, its bindView():

@Override
public void bindView(View view, Context context, Cursor cursor) {
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.nameText.setText(cursor.getString(2) + ", " + cursor.getString(1));
    Cursor values = getContactValues(cursor.getString(0));
    values.moveToLast();
    if (values.moveToFirst()) {
        do {
            if (values.getPosition() == 0) {
                holder.type0Text.setText(replaceType(values.getString(0), context) + ": ");
                holder.num0Text.setText(values.getString(1));
            } else {
                holder.type1Text.setText(replaceType(values.getString(0), context) + ": ");
                holder.num1Text.setText(values.getString(1));
            }
        } while (values.getPosition() < 2 && values.moveToNext());

        int pos = values.getPosition();
        if (pos == 1) {
            holder.type1Text.setVisibility(View.GONE);
            holder.num1Text.setVisibility(View.GONE);
        }
        if (values.getPosition() == 2) {
            holder.type1Text.setVisibility(View.VISIBLE);
            holder.num1Text.setVisibility(View.VISIBLE);
        }
    }
    values.close();

}

its newView:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View view = View.inflate(context, R.layout.contact_item, null);
    ViewHolder holder = new ViewHolder();
    holder.nameText = (TextView) view.findViewById(R.id.textViewName);
    holder.type0Text = (TextView) view.findViewById(R.id.NumLabel0);
    holder.type1Text = (TextView) view.findViewById(R.id.NumLabel1);
    holder.num0Text = (TextView) view.findViewById(R.id.textViewPhoneWork);
    holder.num1Text = (TextView) view.findViewById(R.id.textViewPhoneMobile);
    view.setTag(holder);
    return view;
}

the creation of the CursorAdapter and its constructor:

cadapter = new ContactListCursorAdapter(view.getContext(), namesCursor, 0, readDB, arg2 + 1);

and:

ContactListCursorAdapter(Context context, Cursor c, int flags, SQLiteDatabase readDB, int _ID) {
super(context, c, flags);
this.readDB = readDB;
Cursor tmpc = readDB.query(SQLiteHelper.TABLE, new String[]{SQLiteHelper._ID}, SQLiteHelper.COLUMN_ID + "=?", new String[]{String.valueOf(_ID)}, null, null, null, null);
tmpc.moveToFirst();
this.list = tmpc.getString(tmpc.getColumnIndex(SQLiteHelper._ID));
}

Whenever the View is displayed or updated I get a warning ot the type:

14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d97830 V.ED.... ......ID 24,24-364,105 #7f09003f app:id/textViewName} during layout: running second layout pass
14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d988b8 V.ED.... ......ID 0,0-165,52 #7f090043 app:id/NumLabel0} during layout: running second layout pass
14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d98ce0 V.ED.... ......ID 165,0-488,52 #7f090044 app:id/textViewPhoneWork} during layout: running second layout pass
14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d9b380 V.ED.... ......ID 24,24-467,105 #7f09003f app:id/textViewName} during layout: running second layout pass
14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d9c408 V.ED.... ......ID 0,0-165,52 #7f090043 app:id/NumLabel0} during layout: running second layout pass
14:25:33.543  27597-27597/com.app W/View﹕ requestLayout() improperly called by android.widget.TextView{41d9c830 V.ED.... ......ID 165,0-488,52 #7f090044 app:id/textViewPhoneWork} during layout: running second layout pass

I have no clue where this error happens... and why.

It also seems like com.android.contacts is suffering the from same problem.

06-16 15:12:10.113  27522-27522/com.android.contacts W/View﹕ requestLayout() improperly called by android.widget.TextView{41ed52f8 V.ED.... ......ID 216,90-936,149 #7f0c000e app:id/cliv_name_textview} during layout: running second layout pass

Solution

  • Well, I know that this is an old thread, but if anyone else has the same problem it was caused in my case due to fastScrollEnabled.

    To get rid of it just remove

        android:fastScrollEnabled="true"
        android:fastScrollAlwaysVisible="true"
    

    Hope it helps anyone.