Android How to find out which checkbox is checked

I am making my first Android app, and I have a problem for which I cannot find the answer anywhere on Google.

I want a list of checkboxed items. I want the element itself and the checkbox to be available.

public class MyItem extends ListActivity { private ArrayList<MyItem> items; public void onCreate(Bundle savedInstanceState) { /* code which creates instances of MyItem and inserts them on the *list* variable */ MyArrayAdapter adapter = new MyArrayAdapter(this, R.layout.my_item, list); setListAdapater(adapter); setContentView(R.layout.items_list); } public onListItemClick(ListView l, View v, int position, long id){ //handles the click on an item } public class MyArrayAdapter extends ArrayAdapter<MyItem>{ private MyItem item; public MyArrayAdapter(Context context, int resourceId, ArrayList<MyItem> list){ //code for the constructor } public getView(int position, View convertView, ViewGroup parent){ convertView = inflater.inflate(resourceId, null); this.item = list.get(position); if (this.item == null) { return convertView; } else{ if (resourceId == R.layout.my_item) { final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox); if(cb != null){ //initially if(chosen) cb.setChecked(true); else cb.setChecked(false); //set listener cb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { if(cb.isChecked()) chosen = true; else chosen = false; } }); } } return convertView; } } } 

Do not worry about the selected variable. I wrote this just for code. In fact, this corresponds to the value in the database. Clicking on an item works fine. However, when I click on the checkbox, what happens is:

  • the checkbox in which I clicked is selected (this is working with the Android user interface).
  • the checkbox that is checked inside is the last one on the screen, depending on what it is, i.e. if 8 elements are displayed on my screen, and I click one of them (no matter which one), the check appears in the correct box, but inside, the eighth element is the one that is checked.

I would be grateful for any help you could give me. Thanks in advance.

+7
source share
4 answers

In fact, support for the chosen implementation is key. Android does some optimization with list views so that you can reuse the list item views to avoid over-creating objects and garbage collection (which often led to jerky scrolling). Thus, you must make sure that, when necessary, you know exactly which list item you are working with.

Say you have 100 list items. Your screen will probably not be able to display all of them. You can only show ten items at a time. Thus, 10 representations (actually viewed hierarchies) are created to display these visible elements. When you scroll to the next ten points, instead of creating 10 new views (20 in total), the list can only create one (to cover the case when half of one item is displayed at the top and half of one at the bottom of the screen, only 11 items are visible on the screen ), and the remaining elements reuse previously created views.

So, a conceptual table representing the first screen might look like this:

  Item view
 ------- --------
 Item 1 View 1
 Item 2 View 2
 Item 3 View 3
 Item 4 View 4
 Item 5 View 5
 Item 6 View 6
 Item 7 View 7
 Item 8 View 8
 Item 9 View 9
 Item 10 View 10

And to scroll down ten points it might look a bit (maybe not quite so, but it gives you an idea):

  Item view
 ------- --------
 Item 11 View 1
 Item 12 View 2
 Item 13 View 3
 Item 14 View 4
 Item 15 View 5
 Item 16 View 6
 Item 17 View 7
 Item 18 View 8
 Item 19 View 9
 Item 20 View 10

So what you can learn from this is that one view can represent different elements when scrolling. This means that your event handlers should be a little more dynamic in how they find the element with which they are associated.

All this will give you a little background so that you can change the way you implement your getView method. Here is your actual problem: the item variable is in the scope of your Adapter . Unfortunately, I assume that your code, which you did not post here, which you replaced with chosen , uses item . You set item whenever an item is created. This means that after creating the first 8 views, item set to the eighth item in your list. Whenever you click on a checkbox, you use item , which is the eighth item, and not the item that corresponds to viewing the list item that you clicked.

Here is the structure for getView that I would recommend:

 public getView(int position, View convertView, ViewGroup parent){ View view = convertView; if (view == null) { view = inflater.inflate(R.layout.my_item, null); } final MyItem item = list.get(position); final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox); // This stores a reference to the actual item in the checkbox cb.setTag(item); if(item.chosen) cb.setChecked(true); else cb.setChecked(false); //set listener cb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // This gets the correct item to work with. final MyItem clickedItem = (MyItem) view.getTag(); if(cb.isChecked()) clickedItem.chosen = true; else clickedItem.chosen = false; } }); return view; } } 

Note that I got rid of the item variable at the class level.

+6
source

try it

 public getView(int position, View convertView, ViewGroup parent){ View view = convertView; if (view == null) { view = inflater.inflate(R.layout.my_item, null); } final MyItem item = list.get(position); // This stores a reference to the actual item in the view view.setTag(item); final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox); //set listener cb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // This gets the correct item to work with. final MyItem clickedItem = (MyItem) view.getTag(); if(cb.isChecked()) clickedItem.chosen = true; else clickedItem.chosen = false; } }); cb.setChecked(item.chosen); return view; } 
+2
source

You must store the isChecked value in the MyItem object and the checkbox checkbox explicitly set in the getView method of your adapter. Use onCheckedChangedListener.

0
source

If I follow your explanations, it looks like you have a list, and each line in the list has a checkbox and a text file. In my application, I have something similar, and instead of making both Checkbox and TextView clickable and reacting to it, I use ListView onItemclick. When you catch that the user clicked an item in the list, then in the code you can check or uncheck the box. This gives a visual impression that the user can check the box, but it is very easy to implement.

0
source

All Articles