0

Is it possible to add one view created during newView(..) as a separate type, so that reuse of just that view is prevented during bindView(...)?

This is what my custom cursorAdapter looks like:

@Override
public void bindView(View vi, Context arg1, Cursor cursor) {
    priority.setText(cursor.getString(cursor.getColumnIndex(TodoTable.COLUMN_PRIORITY)));TextView timeElapsed =  (TextView)vi.findViewById(R.id.todayTime); //time
    long id = cursor.getLong(cursor.getColumnIndex(TodoTable.COLUMN_ID));

    if(ts.getRunning() == id){
        ts.startTimer(vi, ts.getCurrentTaskStart(), id);
    }else{
        long time = cursor.getLong((cursor.getColumnIndex(TodoTable.COLUMN_TIME)));
        timeElapsed.setText(ts.getTimeString(0, 0, time));
    }
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup arg2) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View vi = inflater.inflate(R.layout.list_item, null);
    bindView(vi, context, cursor);
    return vi;
}

I tried adding it to a different type, using getItemViewType and getViewTypeCount but that can only deals with positions and not the IDs associated with the rows of the listview.

I want to prevent the view with ts.getRunning() == id at the time of creation being reused at other positions when I scroll. How would I do something like this?

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191

2 Answers2

2

Override the getView method. If you look at the source code of CursorAdapter (link), you'll see a place where they check if the view is null. You just need to copy the whole method, and add an additional if check for ts.getRunning() == id

Here is how it should now look like -

public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null || ts.getRunning() == id) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}

Thankfully, it looks like all the fields used in that method are protected, so you should not run into any problems.

Abhinav Manchanda
  • 6,546
  • 3
  • 39
  • 46
2

If you want to prevent the reuse of view at a certain position the do the following

@Override
public int getItemViewType(int position) {
    mCursor.moveToPosition(position);
    if (mCursor.getLong(mCursor.getColumnIndex(TodoTable.COLUMN_ID)) == ts.getRunning()){
        return IGNORE_ITEM_VIEW_TYPE;
    }
    return super.getItemViewType(position);
}

If you return IGNORE_ITEM_VIEW_TYPE in getItemViewType(position) then the view at that position will not be recycled. More info about IGNORE_ITEM_VIEW_TYPE is here

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
Sreejith Krishnan R
  • 1,244
  • 10
  • 12
  • I don't know the position, with respect to the listview. Only the ID field in the cursor associated. Is there a way to get one from the other? – Anirudh Ramanathan Dec 30 '12 at 15:05
  • 1
    You don't need to know the position. When you scroll the list and when at that position of cursor the value of column COLUMN_ID is equal to `ts.getRunning()` then at that position the view will not be recycled – Sreejith Krishnan R Dec 30 '12 at 15:09
  • 1
    @SreejithKrishnanR Hello, How it work ? IGNORE_ITEM_VIEW_TYPE should check in newView or bindView ? or automatic perevent show view ?? please help me thanks :(( – Online98 Apr 12 '15 at 12:19