2

I'm having a list View with each item composed of a collection of Textviews and a CheckBox. I'm storing the state of the checkbox in the DB and updating it from a on clickListener .It works fine for the controls that are visible.By default all the checkbox's are in the checked state.

If there are 10 items and screen can accommodate 7, then when I Uncheck the first one and scroll to the 10th item and again scroll back to the first one. The first one looses its state( it gets checked again).I checked the DB for the rows state, which is reflected correctly. But the fetch in the BindView always get me the wrong state. I'm not able to pin down where the issues is. I have attached the list adaptor along with this for review...

// List Adaptor code

public class ListAdaptor extends CursorAdapter {

private LayoutInflater mInflater;
Cursor  dataCursor;
Context context;
ListView mLv;

private static final String TAG = "Delete";

public ListAdaptor(Context context, Cursor cursor, ListView lv) 
{
    super(context, cursor);
    this.context = context;
    mLv = lv;
    mInflater   = LayoutInflater.from(context);
}

@Override
public void bindView(View view, Context context, final Cursor cursor) {

    // Get the stored tag for the view

    CheckBox tmp_Chk    = (CheckBox)view.findViewById(R.id.chkbox);
    String selText = cursor.getString(11); 

    // Debug Message
    int val = cursor.getPosition();

    tmp_Chk.setChecked(false);

    SparseBooleanArray sba = mLv.getCheckedItemPositions();
    if(sba != null)
    if(sba.get(cursor.getPosition()))
        tmp_Chk.setChecked(true);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) 
    {
        View newView = mInflater.inflate(R.layout.listviewlyt, null);
        return newView;
    }

}

// Item layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<CheckBox
    android:id="@+id/chkbox"
    android:focusable="false"
    android:clickable="false"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

</CheckBox>


<TextView
    android:id="@+id/label"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@+id/label"
    android:textSize="18sp"
    android:textColor="#000000" >
</TextView>



</LinearLayout>

// List control code in the Main Activity

lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    int lv_Pos = ListView.INVALID_POSITION;
    CheckBox tmp_Chk    = (CheckBox)view.findViewById(R.id.chkbox);
    if (lv_Pos != ListView.INVALID_POSITION) {
        if(tmp_Chk.isChecked()){
            Check_Uncheck(Integer.toString(lv_Pos + 1), 1);
    }
    else if(!tmp_Chk.isChecked()){
        Check_Uncheck(Integer.toString(lv_Pos + 1), 0);
    }   
}

public void Check_Uncheck(String deleteItem , int select)
{
    // Initialize database
    DB dbAdapters = DB.getDBAdapterInstance(TabActivity.this);
    dbAdapters.openDataBase();

    ContentValues cv_InitialValues = new ContentValues();
    cv_InitialValues.put("Selection", select);

    dbAdapters.b_UpdateRecordInDB("Items", cv_InitialValues, "_id=?", new String[] {deleteItem});
    dbAdapters.close();
}

});

// List view XML Properties in the Main activity

<ListView 
    android:id="@+id/LV_Instore_CartTab"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textSize="2px"
    android:layout_weight="1"
    android:choiceMode="multipleChoice"/>
Phoenix
  • 79
  • 1
  • 12
  • I had answered this here "http://stackoverflow.com/a/8410557/525978" if this does not help..let me know ...I can go over your code... – havexz Dec 09 '11 at 00:35
  • a quick question, does the other values retrieve properly? or is it only the Checkbox giving the problem? – Vamsi Dec 09 '11 at 03:22
  • @Vamsi, other values r retrieved properly. – Phoenix Dec 09 '11 at 03:54
  • @havexz / Bobakke4 I have a doubt, what is the difference between BindView and Getview. I see that what ever you people are suggesting is already done in the BindView method. Thank you for your help... – Phoenix Dec 09 '11 at 03:56
  • Well both works fine. bindView if using CursorAdapter and getView if using ListAdapter or BaseAdapter – havexz Dec 09 '11 at 03:58
  • @havexz I tried "stackoverflow.com/a/8410557/525978" post, it didn't work for me. I use a cursor adaptor, and the changes I made are 1) Added setOnItemClickListener to the List view. Moved all the code from the checkbox's onclickabe to this fucntion. 2) Made List view as Multi choice.3) Checkbox non Clickable / Focusable . – Phoenix Dec 09 '11 at 05:03
  • so what exactly is happening? Like to share your updated code with Pastebin or something? – havexz Dec 09 '11 at 05:08
  • @havexz I have modified the query with the latest changes. – Phoenix Dec 09 '11 at 17:40
  • can you explain the business logic a bit..what should happen when user clicks on an item? And also looks like you are not extending from ListActivity..any reason for that? – havexz Dec 09 '11 at 18:24
  • @havex Business Logic: The list view represents, the rows in the local database. When an item is unchecked /Checked, then it should be communicated to the local DB, which syncs up with the server. Once the sync is complete teh list control is updated with the accordingly. The reason why I hvn't used the ListActivity is that I have other controls in addition to the ListView. – Phoenix Dec 09 '11 at 18:45
  • Ok...but you can have other views in a Activity which is extended from ListActivity. Just try changing it. I cant start chat with you as dont have enough repo as of now...:-/ – havexz Dec 09 '11 at 20:57
  • @havexz Thank you. I have fixed it following your stack over flow link. I modified the activity to derive from ListActivity... – Phoenix Dec 14 '11 at 19:56
  • Good to know, if you like you can upvote that one.. – havexz Dec 14 '11 at 21:12

2 Answers2

1

You will want to override getView in your adapter. This function is called as views come into view when the list is scrolled. The convertView variable is the view that has just gone out of view as you scroll and is being reused. The convertView may be null so you should check if it is null and inflate a new row layout if it is null, otherwise you can use the convertView just like you would if you had inflated it. Now what is happening to you is that the view is being reused but you are not setting the state back to how you want it in the getView function. In this function you should use the position variable passed in to determine which item in your list the view is being connected with. If you store the state of the check in the list of objects you can then use the position to get the correct item out of your list. Use the object you retrieve from the list to either check or uncheck the checkbox in your row.

Bobbake4
  • 24,509
  • 9
  • 59
  • 94
0

I am not really aware of CompundButton, but can you try the below code snippet,

tmp_Chk.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            if ( !tmp_Chk.isChecked()) {
                tmp_Chk.setChecked(false);  
                Check_Uncheck();
            } else {
                Check_Uncheck();
                tmp_Chk.setChecked(true);

            }
        }
    });

    if (cursor.getInt(11) == 0) {
        tmp_Chk.setChecked(false);
    } else {
        tmp_Chk.setChecked(true);
    }
Vamsi
  • 5,853
  • 6
  • 29
  • 36