Workforce7
Workforce7

Reputation: 41

bindView being called endlessly in custom CursorAdapter

I have a ListView which is served by a custom CursorAdapter. The ListView rows are very simple - a CheckBox on the left, and two TextViews. When a checkbox is "clicked", action mode is started so that the user can delete multiple items from the List.

While battling to deal with checkboxes and OnItemClickedListeners and keeping track of which boxes were checked, I noticed that bindView was being called endlessly. And, I really do mean endlessly: if the ListView has one item or 100, bindView is called multiple times a second for the duration of the fragment's lifecycle. The ListView now behaves exactly as I wanted it to, but there is clearly something VERY wrong with my code, or my XML layouts.

Searching for an answer on this site has not yelded results, so I'm posting my very first question here.

My XML layout for each row of the ListView looks like this:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:paddingBottom="@dimen/activity_vertical_margin" 
     android:paddingTop="@dimen/activity_vertical_margin"
     android:descendantFocusability="blocksDescendants"    
     >

    <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
      android:focusable="false"
      android:clickable="false"
      android:id ="@+id/chkBox" />
    <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" 
      android:text="Some example text"
      android:layout_weight=".5"
      android:id="@+id/txtExercise" />
    <TextView 
      android:id="@+id/txtDuration"
      android:layout_width="fill_parent" android:layout_height="wrap_content"
      android:text="0:00" android:gravity="right"
      android:layout_weight=".5" >

    </TextView>


     </LinearLayout>

I'm not sure what other code to show here, so I'm going to put my newView and bindView methods in. Hopefully, that will be enough for someone to help me identify the problem.

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {     
    final LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(layout, parent, false);
    Log.i(TAG, "newView=" + parent.getId());

    final ViewHolder holder = new ViewHolder();
    holder.txtExercise = (TextView) v.findViewById(R.id.txtExercise);
    holder.txtDuration = (TextView) v.findViewById(R.id.txtDuration);
    holder.check = (CheckBox) v.findViewById(R.id.chkBox);                  
    holder.check.setOnCheckedChangeListener(new OnCheckedChangeListener(){

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
            checkedList.put((Integer) buttonView.getTag(),checked);             
        }

    });
    v.setTag(holder);       
    return v;
}


@Override
public void bindView(View v, Context arg1, Cursor c) {
    String exercise = c.getString(c.getColumnIndex("_ExcerciseName"));
    int sec = c.getInt(c.getColumnIndex(WorkoutLog.DURATION));
    String duration = returnDurationString(sec);
    Log.i(TAG, "bindview called");
    ViewHolder holder = (ViewHolder) v.getTag();

    if(holder.txtExercise !=null)
        holder.txtExercise.setText(exercise);
    if(holder.txtDuration != null)
        holder.txtDuration.setText(duration);
    if(holder.check !=null) {   
        holder.check.setTag(c.getInt(c.getColumnIndex(WorkoutLog._ID)));
        int x = (Integer) holder.check.getTag();            
        holder.check.setChecked(checkedList.get(x));            
    }
}

Any advice would be appreciated! I'm still very new to Android development, so I'm probably making some completely idiotic mistake, but I just don't have the experience and/or knowledge to try and resolve this.

[Edit] - removing the tags from around my ListView solved the problem!

Upvotes: 0

Views: 1790

Answers (1)

amp
amp

Reputation: 12352

I'm supposing you have your android:layout_height of your listview set to wrap_content. Try to switch to fill_parent.

Check this answer: Why does Wrap_Content fire BindView more than once

Something like:

<ListView
        android:id="@+id/my_listView"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        //...
</ListView>

Hope this help!

Upvotes: 3

Related Questions