0

I have a problem by selecting CheckBoxes in my ListItems. Each ListItem has a CheckBox in it's layout and when the ListItem is clicked the CheckBox should be activated. The problem is that the CheckBoxes are randomly activated. For example: When i have 2 ListItems and click on ListItem1, it's CheckBox is activated. When i click again, CheckBox of ListItem2 is activated, too. When i click again, CheckBox of ListItem1 is deactivated. When i click again, CheckBox of ListItem2 is deactivated. When i click again it all starts from the beginning. I understand ListView reuses the Items and that i have to use getView() method, but i just can't make it work. I have to mention that I'm a bloody beginner, so please forgive me if some code doesn't make sense at all.

user1617102
  • 61
  • 2
  • 9
  • 1
    check [this](http://stackoverflow.com/questions/12001143/custom-listview-with-checkbox-single-selection/12003125#12003125) may help you – swiftBoy Aug 22 '12 at 14:02
  • How can i make it work with a custom ListItem XML? That example seems only to work with a standard ListItem layout. Nonetheless it's interesting that this example isn't using getView() to make it work. – user1617102 Aug 22 '12 at 14:26
  • Okay so you want ListView with checkBox and Custom Array Adapter??I am trying to make a code for you hold a bit!! – swiftBoy Aug 22 '12 at 14:32

3 Answers3

0

Try using setOnItemSelectedListener instead of setOnItemClickListener . I believe the click event is getting invoked more often that you need.

Sameer
  • 4,314
  • 1
  • 19
  • 22
0

You need to store the item states in your Adapter, not in the View itself, because it could be a reused one, just like you say. Your call to super.getView() will fill in the correct text for you, but not change the checkbox state. Keep a bool array reflecting the state of each checkbox, and in getView() apply the state before returning your view:

CheckBox cb = (CheckBox) view.findViewById(R.id.cb);
cb.setChecked(cbStates[position]);
ekholm
  • 2,513
  • 15
  • 18
  • Ok, this makes sense. I tried to implement it to my code, but i always get a NULLPOINTEREXCEPTION on this line: "for(int i = 0; i < cbStates.length; i++){". What am i doing wrong? – user1617102 Aug 22 '12 at 15:26
0

You need to create a Custom Array Adapter and all set.

Here is the Activity Class I created for ListView for ChekBoxList

ActivityGamesList.java

package com.rdc.gameListApp;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Toast;

public class ActivityGamesList extends Activity {

     private ListView listGames = null; 
     private DBAdapter database = null;
     private Context context = null;    

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_of_games);

        final CheckBox favBox = (CheckBox) findViewById(R.id.favbuttonInList);
        listGames = (ListView) findViewById(R.id.listViewGame); 

        context = getApplicationContext();
        database = new DBAdapter(context);

        //here I am getting the data from database and  putting in to List
        List<String> gamelistArrayR = database.selectAllName();     

        // custom adapter for adding fav box
        //make sure here "gamelistArrayR" is List and type is String
        listGames.setAdapter(new CustomAdapter(this, gamelistArrayR));

        //listener for list view
        listGames.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

                Toast.makeText(getApplicationContext(), "You have selected:  " +
                          position+" no row", Toast.LENGTH_SHORT).show();

            }
        });
    }

}

and below is the Custom Array Adapter

CustomAdapter.java


package com.rdc.gameListApp;

import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;

public class CustomAdapter extends ArrayAdapter<String> {
    private final Context context;
    private final List<String> values;

    public CustomAdapter(Context context, List<String> gamelistArrayR) {
        super(context, R.layout.list_row_custom, gamelistArrayR);
        this.context = context;
        this.values = gamelistArrayR;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.list_row_custom, parent, false);

        //Game Name Text in list
        TextView textView = (TextView) rowView.findViewById(R.id.txtGameNameInList);
        // Check Box in list
        CheckBox favBox = (CheckBox) rowView.findViewById(R.id.favbuttonInList);

        textView.setText(values.get(position));         

        //listener for check box
        favBox
        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
                Boolean flag = isChecked;               
                if(flag){                   

                        Log.v("Debug", "step no 1");
                        Toast.makeText(context, "Marked as Favorite Game!", 1).show();                  
                }
            }
        }); 
        return rowView;
    }
}

and i got the output like this way..

enter image description here

Edit:

When you scroll list, the chekboxrs gets uncheked because or recreate view.

so you need to store the state of checkbox for that you should check below links

this So thread or this tutorial

Community
  • 1
  • 1
swiftBoy
  • 33,793
  • 26
  • 129
  • 124
  • The code basically works, but the CheckBoxes are only highlighted when i press them. They are not selected. EDIT: My fault. I now deleted "android:choiceMode="multipleChoice" in my . Now the code works perfect. :) Thumbs up and thanks for your help. – user1617102 Aug 22 '12 at 16:23
  • your welcome..really happy to see this.. :) soon i am going to create a Tutorial for this and post on my blog – swiftBoy Aug 22 '12 at 18:57
  • Like i said, it works now, but there's another problem. When an activated CheckBox scrolls out of screen then it deactivates itself. How can i prevent this? Does ConvertView have something to do with this? – user1617102 Aug 22 '12 at 18:59
  • for that you need to store the state of selected CheckBox ..see Updated answer – swiftBoy Aug 22 '12 at 19:13
  • Ok, that seems to be a little bit more complex than i thought. I'll keep working on it tomorrow and will post here if it works. – user1617102 Aug 22 '12 at 19:59
  • The code of the tutorial causes 2 errors. Error 1 is in this line: "list.get(getPosition).setSelected(buttonView.isChecked());" Error message: "The method setSelected(boolean) is undefined for the type String". Error 2 is in this line: "viewHolder.checkbox.setChecked(list.get(position));" Error message: "The method setChecked(boolean) in the type CompoundButton is not applicable for the arguments (String)". Well, "list" is an ArrayList, but don't these commands only get the position in the Array? – user1617102 Aug 23 '12 at 12:15