0

I'm experiancing a problem with CheckBox.It changes it's state while scrolling. After looking for a while for its solution I found Android: CursorAdapter, ListView and CheckBox where getView is preferred to bindView for CursorAdapters' optimization .So I thought of applying it in my case.So here is my code:

package com.example.ki;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
DBAdapter myDb;            
ListView myList;
Cursor c;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    openDB();
    display();
    insert();
    }
private void insert() {
    myDb.insertRow("0",false);
    myDb.insertRow("1",true);
    myDb.insertRow("2",true);
    myDb.insertRow("3",false);
    myDb.insertRow("4",false);
    myDb.insertRow("5",false);
    myDb.insertRow("6",false);
    myDb.insertRow("7",true);
    myDb.insertRow("8",false);
    myDb.insertRow("9",false);
    myDb.insertRow("10",false);
    myDb.insertRow("11",false);
    myDb.insertRow("12",false);
    myDb.insertRow("13",false);
    myDb.insertRow("14",false);
    myDb.insertRow("15",false);
    myDb.insertRow("16",false);
    myDb.insertRow("17",false);
    myDb.insertRow("18",false);
    myDb.insertRow("19",false);
    myDb.insertRow("20",false);
    myDb.insertRow("21",false);
    myDb.insertRow("22",true);
    Toast.makeText(this, "insett(); method called...", Toast.LENGTH_LONG).show();
    }
@Override
protected void onDestroy() {
super.onDestroy();  
closeDB();
}
private void openDB() {
myDb = new DBAdapter(this, null, false);
myDb.open();
}
private void closeDB() {
myDb.close();
}
// Display ListView with CheckBoxes
private void display() {
    c = myDb.getAllRows();
    String[] fromFieldNames = new String[]{DBAdapter.KEY_NAME};
    int[] toViewIDs = new int[]{R.id.textsv};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter= new    SimpleCursorAdapter(getBaseContext(),R.layout.item_layoutt, c , fromFieldNames ,   toViewIDs ,0);
    final ListView myList = (ListView) findViewById(R.id.listView1);
    myList.setAdapter(myCursorAdapter);
        }


public class MyDataAdapter extends SimpleCursorAdapter {


private Context context;

private ArrayList<String> myList = new ArrayList<String>();
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();

private Cursor cur;

// itemChecked will store the position of the checked items.

public MyDataAdapter(Context context, int layout, Cursor c, String[] from,
    int[] to,int k) {
 super(context, layout, c, from, to, k);

 this.cur = c;
 this.context = context;
 for (int i = 0; i < this.getCount(); i++) {
    itemChecked.add(i, false); // initializes all items value with false
 }
 }
 @Override
 public View getView(final int pos, View inView, ViewGroup parent) {
 if (inView == null) {
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inView = inflater.inflate(R.layout.item_layoutt, null);
 }
 final CheckBox cBox = (CheckBox) inView.findViewById(R.id.textcb); // your
 // CheckBox
 cBox.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        CheckBox cb = (CheckBox) v.findViewById(R.id.textcb);
        if (cb.isChecked()) {
            itemChecked.set(pos, true);
            // do some operations here
        } else if (!cb.isChecked()) {
            itemChecked.set(pos, false);
            // do some operations here
        }
    }
});
cBox.setChecked(itemChecked.get(pos)); // this will Check or Uncheck the
// CheckBox in ListView
// according to their original
// position and CheckBox never
// loss his State when you
// Scroll the List Items.
return inView; 
}}
}

Problems :
1. What's the use of private ArrayList myList = new ArrayList(); ?

2. private Cursor cur; isn't used. It shows error in Eclipse: The value of the field MainActivity.MyDataAdapter.cur is not used.

3. Why are there two CheckBoxes

final CheckBox cBox = (CheckBox) inView.findViewById(R.id.textcb); // your // CheckBox

and

CheckBox cb = (CheckBox) v.findViewById(R.id.textcb);

called ?

I don't to how to make this code work (I 'm new to Android).
Community
  • 1
  • 1
babiro
  • 95
  • 2
  • 11
  • It would be better if you use `onCheckChangedListener` instead of `OnClickListener` – k1slay Jun 02 '15 at 10:50
  • I did it,But it warns **The method setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener) in the type CompoundButton is not applicable for the arguments (new onCheckChangedListener(){})** – babiro Jun 02 '15 at 11:29

1 Answers1

0

The second point is valid, if cur is not used remove it.

For the first point, the arraylist keeps track of your positions and the values associated with them. Its a name value list: name: position1 Value (true/false/) depending on the check. You init all of the name value pairs to false in the constructor like a fresh list would be - without any checks.

For the third point both of your cb and cBox refer to the same view.

cBox.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        CheckBox cb = (CheckBox) v.findViewById(R.id.textcb);
        if (cb.isChecked()) {
            itemChecked.set(pos, true);
            // do some operations here
        } else if (!cb.isChecked()) {
            itemChecked.set(pos, false);
            // do some operations here
        }
    }
});

Notice how your view is passed:

 public void onClick(View v) {
 CheckBox cb = (CheckBox) v.findViewById(R.id.textcb);

Look at the arguments. If you dont want to do it twice, you will have to declare cBox as final. Which is a sub-optimal solution.

Below is a working implementation:

private class CurAdapter extends CursorAdapter implements SectionIndexer{

        AlphabetIndexer mAlphabetIndexer;
        public CurAdapter(Context context, Cursor c, int flags) {


            super(context, c, flags);


            for (int i = 0; i < c.getCount(); i++) {
                itemChecked.add(i, false); 
            }

            mAlphabetIndexer = new AlphabetIndexer(c ,c.getColumnIndex("NotificationDateFor")," ABCDEFGHIJKLMNOPQRTSUVWXYZ");
            mAlphabetIndexer.setCursor(c);

        }

        @Override
        public int getPositionForSection(int sectionIndex){
            return mAlphabetIndexer.getPositionForSection(sectionIndex);
        }


        @Override
        public int getSectionForPosition(int position){
            return mAlphabetIndexer.getSectionForPosition(position);
        }


        @Override
        public Object[] getSections(){
            return mAlphabetIndexer.getSections();
        }

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

            final ViewHolder holder = (ViewHolder) view.getTag();
            final int position = cursor.getPosition();
            String name = (cursor.getString(cursor.getColumnIndexOrThrow("NotificationDateFor")));
            String image = cursor.getString(cursor.getColumnIndexOrThrow("imageUri"));
            String radio = cursor.getString(cursor.getColumnIndexOrThrow("RadioType"));
            String type = cursor.getString(cursor.getColumnIndexOrThrow("TypeNotification"));
            String friendsname = cursor.getString(cursor.getColumnIndexOrThrow("FriendsName"));



            holder.nametext.setTextColor(Color.parseColor("#000000"));
            holder.nametext.setText(name);
            holder.subtext.setText("");
            holder.subtext.setTextColor(Color.parseColor("#000000"));
            setImage(image, holder.iv); 
            holder.chk.setButtonDrawable(id);



            


            holder.chk.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v) {

                    if (holder.chk.isChecked()) { 
                        itemChecked.set(position, true);
                        addlist.setItemChecked(position,true);

                    } else if (!holder.chk.isChecked()) {
                        itemChecked.set(position, false);
                        addlist.setItemChecked(position,false);

                    }   
                }               
            });

            holder.chk.setChecked(itemChecked.get(cursor.getPosition()));
        } 
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {

            View view = LayoutInflater.from(context).inflate(R.layout.group_list, null);

            ViewHolder holder = new ViewHolder(view);
            view.setTag(holder);
            return view;

        }




        public class ViewHolder {
            TextView nametext, subtext;
            RoundedImageView iv; 
            CheckBox chk; 

            public ViewHolder(View view){

                iv = (RoundedImageView)view.findViewById(R.id.imageView2);
                nametext = (TextView) view.findViewById(R.id.textView1);
                subtext = (TextView) view.findViewById(R.id.textView2);
                chk = (CheckBox) view.findViewById(R.id.checkBox1);

            }



        }

    }
Community
  • 1
  • 1
Skynet
  • 7,820
  • 5
  • 44
  • 80
  • If I remove cur , it warns "create field cur in type MyDataAdapter" ,still checkbox states change. In this snippet http://stackoverflow.com/questions/4803756/android-cursoradapter-listview-and-checkbox/4804366#4804366 , it uses ** final CheckBox cBox = (CheckBox) inView.findViewById(R.id.bcheck); // your // CheckBox ** and ** CheckBox cb = (CheckBox) v.findViewById(R.id.your_checkbox_id); ** , But Why not a single CheckBox .(In my case I've equalled these CheckBox ids) – babiro Jun 02 '15 at 10:51
  • Thanks dude, I'm waiting :) – babiro Jun 02 '15 at 11:06
  • Check that! I have edited my answer. However bear in mind that the above implementation is not optimized for view recycling. – Skynet Jun 02 '15 at 12:18