0

I know that this question has been asked over and over again but still I've not been able to find a helpful suggestion. Check box is getting unchecked when I scroll the List view. I am using Array List to store id of a selected item in the list view when particular item is unchecked it is removed from List view.

public class ManagePracticeLogAdapter extends BaseAdapter   
{

    Context context;
    LayoutInflater inflater;
    MenuItem menu,addlog;
    List<Integer> SelectedBox;
    ArrayList<HashMap<String, String>> data;
    HashMap<String, String> resultp = new HashMap<String, String>();

    public ManagePracticeLogAdapter(
        Context context, 
        ArrayList<HashMap<String, String>> arraylist, 
        MenuItem mymenu,
        MenuItem myaddlog)
    {
        this.context = context;
        data = arraylist;
        menu=mymenu;
        addlog=myaddlog;
    }

    @Override
    public int getCount() 
    {
        return data.size();
    }

    @Override
    public Object getItem(int position) 
    {
        return null;
    }

    @Override
    public long getItemId(int position)
    {
        return 0;
    }

    // Method  to display data of Produce log Activity in list view 
    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        // TODO Auto-generated method stub
        TextView datetime;
        TextView totminutes;
        TextView skills;
        TextView weather;
        final CheckBox chkdelete;


        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.logitem1, parent, false);
        // Get the position
        resultp = data.get(position);

        // Locate the TextViews in listview_item.xml
        datetime = (TextView) itemView.findViewById(R.id.id_datetime);
        totminutes = (TextView) itemView.findViewById(R.id.totminutes);
        skills= (TextView) itemView.findViewById(R.id.id_skills);
        weather=(TextView)itemView.findViewById(R.id.id_weather);

        chkdelete=(CheckBox)itemView.findViewById(R.id.id_chkDelete);

        // Capture position and set results to the TextViews
        datetime.setText(resultp.get("Skill_practice"));
        totminutes.setText(resultp.get("Day_minutes")+" min");
        skills.setText(resultp.get("Night_minutes"));
        weather.setText(resultp.get("Prac_Date"));
        String fontPath = "fonts/Roboto-Light.ttf";
        Typeface tf = Typeface.createFromAsset(context.getAssets(), fontPath);
        datetime.setTypeface(tf);
        totminutes.setTypeface(tf);
        skills.setTypeface(tf);
        weather.setTypeface(tf);



        SelectedBox = new ArrayList<Integer>();
        chkdelete.setOnCheckedChangeListener(new OnCheckedChangeListener() 
        {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            {
                if(SelectedBox.size()-1==0)
                {
                    menu.setVisible(false);
                    addlog.setVisible(true);
                }else
                {
                    addlog.setVisible(false);
                }
                if(isChecked)
                {
                    SelectedBox.add(buttonView.getId());
                    menu.setVisible(true);
                    addlog.setVisible(false);

                }else if(!isChecked)
                {

                    SelectedBox.remove(SelectedBox.indexOf(buttonView.getId()));

                }

            }
        });



        menu.setOnMenuItemClickListener(new OnMenuItemClickListener()
        {

            @Override
            public boolean onMenuItemClick(MenuItem item)
            {
                // TODO Auto-generated method stub

                if(!SelectedBox.isEmpty())
                {
                    Toast.makeText(context, "Menu option 4 added!", 
                        Toast.LENGTH_LONG).show();

                }

                return false;
            }
        });



        itemView.setOnClickListener(new OnClickListener() 
        {

            @Override
            public void onClick(View arg0)
            {
                Intent intent = new Intent(context,LogEdit.class);
                intent.putExtra("s11","Update Practice");
                context.startActivity(intent);

            }
        });
        return itemView;
    }

}
JJD
  • 50,076
  • 60
  • 203
  • 339
user3651987
  • 21
  • 1
  • 13
  • because listview recycles view. Check this http://stackoverflow.com/questions/18162931/get-selected-item-using-checkbox-in-listview – Raghunandan Jun 17 '14 at 06:37
  • Go through my [this answer](http://stackoverflow.com/questions/23512344/how-to-show-installed-app-list-in-a-listview-without-checkbox-getting-unchecked/23577344#23577344),it will help you. – Pankaj Arora Jun 17 '14 at 06:51

3 Answers3

2

Your getView method should look like this

Create a ViewHolder class

static class ViewHolder {
        TextView datetime;
        TextView totminutes;
        TextView skills;
        TextView weather;
        CheckBox chkdelete;
    }

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder viewHolder = null;
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.logitem1, null);
        viewHolder = new ViewHolder();
        viewHolder.datetime = (TextView) convertView.findViewById(R.id.id_datetime);
        // do the same thing for other textviews and checkbox.
        viewHolder.chkdelete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.

            }
        });
        convertView.setTag(viewHolder);
        convertView.setTag(R.id.id_datetime, viewHolder.datetime);
        // do the same for other textviews and checkbox
        } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.chkdelete.setTag(position); // This line is important.

    viewHolder.datetime.setText(resultp.get("Skill_practice"));
    // do the same for others

    return convertView;
}

You need to modify it according to your needs. This code will solve your problem on scroll.

Aniruddha
  • 4,477
  • 2
  • 21
  • 39
0

You need to use for example a sparse boolean array. https://groups.google.com/forum/?fromgroups#!topic/android-developers/No0LrgJ6q2M

Listview are recycled so you basically need to save the state of your checkbox somewhere.

Juste create a sparse boolean array with a size [number of checkbox].

When one of your checkbox is clicked, get his position and set in the sparse boolean array the element (at this position) to true.

In the create view just set the checkbox to the state "enabled" IF your sparse boolean is true.

And you should use a view holder instead of creating new object each time.

Good luck !

maxime1992
  • 22,502
  • 10
  • 80
  • 121
  • If you're able to read a french article, the best one about custom listview is : http://dahliascherr.blogspot.fr/2012/04/tutorial-android-les-listes.html – maxime1992 Jun 17 '14 at 06:40
0

The buttonView in

onCheckedChanged(CompoundButton buttonView, boolean isChecked) 

refers to the last item of the adapter. This is because adapter is used to recycle view. To access the id , store it in the tag.

chkdelete.setTag(R.id.id_chkDelete);

Finally you can access the id of the view via its tag inside onCheckedChanged() as

int checkBoxId=(int) view.getTag().toString();

Finally, your code looks like

    SelectedBox = new ArrayList<Integer>();
    chkdelete.setTag(R.id.id_chkDelete);
    chkdelete.setOnCheckedChangeListener(new OnCheckedChangeListener(){

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
        {
            int checkBoxId=(int) view.getTag().toString();
            if(SelectedBox.size()-1==0)
            {
                menu.setVisible(false);
                addlog.setVisible(true);
            }else
            {
                addlog.setVisible(false);
            }
            if(isChecked)
            {
                SelectedBox.add(checkBoxId);
                menu.setVisible(true);
                addlog.setVisible(false);
            }else if(!isChecked)
            {
                SelectedBox.remove(SelectedBox.indexOf(checkBoxId));
            }

        }
    });
makata
  • 2,188
  • 2
  • 28
  • 23