I have a listview from which I remove selected items, I am doing this through a SparseBooleanArray.
However when I remove the selected items, I also want them removed from that position from 2 other arraylists (trackedItems, dateWatchList) but in the dateWatchList arraylist always 1 item it not removed.
I already checked several threads but I cannot get this right.
Would be great if someone can help.
Code piece:
...
SparseBooleanArray checkedItems = lv.getCheckedItemPositions();
for (int i = 0; i < adapter.getCount(); i++) {
if (checkedItems.get(i)) {
// This item is checked and can be removed
trackedItems.remove(i);
dateWatchList.remove(i); // 1 item always remains and is NOT removed?
adapter.remove(adapter.getItem(i));
}
}
checkedItems.clear();
adapter.notifyDataSetChanged();
...
I solved it myself, for anyone who has the same problem, here is my working code:
SparseBooleanArray checkedItems = lv.getCheckedItemPositions();
for (int i = checkedItems.size()-1; i >= 0; i--) {
String selecteditem = adapter.getItem(checkedItems.keyAt(i));
String currentName = trackedItems.get(checkedItems.keyAt(i));
long currentDate = dateWatchList.get(checkedItems.keyAt(i));
if (checkedItems.get(checkedItems.keyAt(i))) {
adapter.remove(selecteditem);
trackedItems.remove(currentName);
dateWatchList.remove(currentDate);
}
}
checkedItems.clear();
adapter.notifyDataSetChanged();
I have a multiSelec listView fills with days. I´m getting the items selected, my problem is when I click in one list field in order to unselect it. An example:
I check the position 1,2,3,4,5 on the list and after that I uncheck the 4,5 position , so finally I have 3 fields checked.
With my code I get 5 values checked instead 3 .
¿Can anyone help me?
What I'm doing wrong?
private void gettingDaysChecked(){
boolean isSomethingChecked = false;
SparseBooleanArray checked = mListView.getCheckedItemPositions();
Log.d(Constants.TAG,"cheched size is "+checked.size() );
if (checked.size()>0)
isSomethingChecked=true;
if (isSomethingChecked) {
for (int i = 0; i < checked.size(); i++) {
int positionItem = checked.keyAt(i);
Log.d(Constants.TAG, "in position" + positionItem);
localList.add(positionItem);
}
app.setDaysCheckedFilterPeriod(localList);
}else if(!isSomethingChecked){
Log.d(Constants.TAG,"nothing checked ");
}
}
SparseBooleanArray selectedItem=catogoryList.getCheckedItemPositions();
for(int i=0;i<selectedItem.size();i++)
{
System.out.println("Array val:"+selectedItem.valueAt(i));
if(selectedItem.valueAt(i))
{
if(temp.contains(list.get(position)))
{}
else
temp.add(list.get(position));
}
else
{
temp.remove(list.get(position));
}
}
I use listview with multiple_choice (listview with checkbox) when i get items in listview that is checked with out scrolling i received correct values if i scroll the listview i don't get correct values. i found that selectedItem.valueAt(i) i get false when i check the items while scrolling. i don't know why false value is returned instead of true value.
How do you obtain your values? This process should be like this:
SparseBooleanArray checked = getCheckedItemPositions();
List<String> checkedResult = new ArrayList<String>();
for (int i = 0; i < checked.size(); i++) {
if (checked.valueAt(i)) {
checkedResult.add(getAdapter().getItem(checked.keyAt(i)).toString());
}
}
return checkedResult;
I have one simple_list_item_multiple_choice listview in my layout and i am trying to remove all the selected items from it. I know how to delete it but i am having two major problems while deleting the items :-
My program isn't deleting more than 2 items like if i selected 4 items then only 2 will be deleted and sometime its even deleting the wrong items.
When i debug my code i found Array IndexOutOfBoundException in my code and as far as i know there is no exception like this in my code and its all because of deleting the wrong or less items.
here is my code:-
public void onClick(View view)
{
SparseBooleanArray checkedPositions = new SparseBooleanArray();
checkedPositions.clear();
checkedPositions = lv.getCheckedItemPositions();
int size = checkedPositions.size();
if(size != 0)
{
try
{
for(int i = 0; i < size; i++)
{
if(checkedPositions.valueAt(i))
{
list.remove(checkedPositions.keyAt(i));
notes.notifyDataSetChanged();
lv.setItemChecked(i,false);
}
}}catch (IndexOutOfBoundsException ie)
{}
}
else{}
}
I caught the exception only for debugging purpose. Thanks in advance but please help because i am stuck at this part since last two days.
Each time you remove an item from the array at the lower lever, the total count is being reduced by 1. If you had 4 items to remove [ 0, 1, 2, 3], and you remove items starting with item 0, you have [0, 1, 2], then you remove item at 1, and you have [0, 1], if you try to remove item at index 2 which does not exist you will get an error. Try count down instead of up like this
for(int i = size; i > 0; --i)
{
if(checkedPositions.valueAt(i))
{
list.remove(checkedPositions.keyAt(i));
notes.notifyDataSetChanged();
lv.setItemChecked(i,false);
}
}
for(int i = size-1 ; i >= 0; i--)
{
if(checkedPositions.valueAt(i))
{
list.remove(checkedPositions.keyAt(i));
//lv.setItemChecked(checkedPositions.keyAt(i),false);
}
}
notes.notifyDataSetChanged();
From the look of it, you should change this
for(int i = 0; i <= size; i++)
to
for(int i = 0; i < size; i++)
I am using an array adapter and to this am adding an array list of string s , the list is multi select , How can i get the values of list items clicked ?
my_contacts_list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,conts_list);
my_contacts_list.setAdapter(adapter);
I was trying to do this ,
SparseBooleanArray positions = my_contacts_list.getCheckedItemPositions();
int size=positions.size();
int i=0;
while(i <= size){
conts_list.get(positions.get(i));
i++;
}
But position.get(i) is an array list , how to retrieve the selected items then ?
SparseBooleanArray.get returns a boolean, but I believe you need to check it for each position in your list, e.g.
int len = listView.getCount();
SparseBooleanArray checked = listView.getCheckedItemPositions();
for (int i = 0; i < len; i++)
if (checked.get(i)) {
String item = cont_list.get(i);
/* do whatever you want with the checked item */
}
This API is a mess. Here is what works for me.
SparseBooleanArray checked = tags.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
if(checked.valueAt(i)) {
Tag tag = (Tag) tags.getItemAtPosition(checked.keyAt(i));
Log.i("xxxx", i + " " + tag);
}
}
I believe the fastest way to get the info out of this SparseArray is to iterate over the keys (actually I'm fairly sure that the solutions above won't work in all cases). The ListView will enter a pair (index, true) into the SparseBooleanArray for every selected index.
So the code might look like this:
SparseBooleanArray checked = lv.getCheckedItemPositions();
int size = checked.size(); // number of name-value pairs in the array
for (int i = 0; i < size; i++) {
int key = checked.keyAt(i);
boolean value = checked.get(key);
if (value)
doSomethingWithSelectedIndex(key);
}
I think the Answer from Daren Robbins is Wrong, here is my answer:
ArrayList<String> ids = extras.getStringArrayList("commonids");
SparseBooleanArray checked = lv.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
if(checked.get(i))
Log.i("CheckedItem", ids.get(checked.indexOfKey(i)));
}
Assume ids is an arraylist with the same size of the listview containing the ids of the items in the list view
The thing is you must iterate all the list view items but not checkedPositions.
Define the variables:
listView (The instance of you ListView)
names (the ArrayList you are )
saveCheckedName (save all checked name to this Arraylist)
SparseBooleanArray checkedPositions = listView.getCheckedItemPositions();
for (int i = 0; i < subjectListView.getCount(); i++) {
if (checkedPositions.get(i) == true) {
saveCheckedName.add(names.get(i));
}
}
Like so many other things, multi-select ListViews are a real problem in Android.
Instead of simply requesting the selected items as a List of Objects (dear Google, this is what we expect):
List selected_items = my_list_view.getSelectedItems();
we are forced to use this stupendously ridiculous API:
SparseBooleanArray checked = my_list_view.getCheckedItemPositions();
int num_selected = 0;
for(int i = 0; i < checked.size(); i++) {
if(checked.valueAt(i)) {
num_selected++;
int key = checked.keyAt(i);
boolean value = checked.get(key);
if (value) {
//
}
}
}
The horribly named SparseBooleanArray is populated by calling the even more horribly named getCheckedItemPositions() on the ListView. But instead of returning the positions of each selected/checked item in the list, it returns the position of every item in the list that WAS EVER touched, whether it is currently actually selected or not! Unbelievable, but true.
To calculate whether the item is ACTUALLY CURRENTLY checked, we are forced to test valueAt(i) for truthiness while looping through the 'was ever touched' array of items.
In addition to this madness, if we want to calculate the number of selected items, we appear to be forced to increment our own counter (e.g. num_selected).
With APIs like this one, it's little wonder developers are an angry lot!
I think another option is to just keep track of all of this yourself.
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> listView, View selectedItem,
int position, long itemId) {
//Keep a reference here, and toggle a global variable.
HOW I SOLVED THE ISSUE with a second ArrayList :
Created a second ArrayList instance
Updated that ArrayList instance with the UNCHECKED items
added it to the my listadapter
public void removeSelectedItems(){
updatedList = new ArrayList<String>(); //initialize the second ArrayList
int count = lv.getCount(); //number of my ListView items
SparseBooleanArray checkedItemPositions = getListView().getCheckedItemPositions();
for (int i=0;i < count;i++){
if(!checkedItemPositions.get(i))
updatedList.add(liveNames.get(i)); //liveNames is the current ArrayList
Log.e("TEST", liveNames.get(i));
}
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice, updatedList);
setListAdapter(adapter);}
Hope it will be helpfull :)
Foo objectAtCheckedRow = null;
for (int i = 0; i < positions.size(); i++) { //positions.size() == 2
objectAtCheckedRow = adapter.getItem(positions.keyAt(i));
//Do something significant with object here
}
A couple things to understand
It's a key-value pair list.
The key is the index of a row, get it with positions.keyAt(i)
The value is whether the row at that index is checked or not(true or false), get it with positions.valueAt(i)
positions.get(i) returns the same boolean as .valueAt(i)
Careful not to get indexes mixed up. You do not need to(and should not) iterate over your whole list. Use int i to iterate over positions, but don't use i to get objects from your list
But in this specific case(listView.getCheckedPositions()) it only fills in true(checked rows), so you don't actually need to verify using .get(i) nor .valueAt(i)
Example:
Let's say you've checked the 5th and 8th items in the list(index 4 and 7), then positions.size() == 2 and i will be 0 and then 1
So when:
i == 0 then keyAt(i) == 4
i == 1 then keyAt(i) == 7
i == 0 OR i == 1 then valueAt(i) == true AND get(i) == true
FYI, Here is how Google did it:
Excerpted from http://mytracks.googlecode.com/hg/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java
/**
* Gets the checked positions in a list view.
*
* #param list the list view
*/
private int[] getCheckedPositions(ListView list) {
SparseBooleanArray positions = list.getCheckedItemPositions();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (int i = 0; i < positions.size(); i++) {
int key = positions.keyAt(i);
if (positions.valueAt(i)) {
arrayList.add(key);
}
}
int[] result = new int[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
result[i] = arrayList.get(i);
}
return result;
}
and here is my adapted version:
public static List<Integer> getAbsListViewCheckedItemPositions(AbsListView absListView) {
SparseBooleanArray checked = absListView.getCheckedItemPositions();
List<Integer> positions = new ArrayList<>();
int checkedSize = checked.size();
for (int i = 0; i < checkedSize; i++) {
if (checked.valueAt(i)) {
positions.add(checked.keyAt(i));
}
}
return positions;
}
We use this in our Android utility class. The generics help prevent compiler warnings, but you can remove them if your adapter returns multiple types.
public static <T> Collection<T> getCheckedItems(ListView listView) {
Collection<T> ret = new ArrayList();
SparseBooleanArray checkedItemPositions = listView.getCheckedItemPositions();
for (int i = 0; i < checkedItemPositions.size(); i++) {
if (checkedItemPositions.valueAt(i)) {
T item = (T) listView.getAdapter().getItem(checkedItemPositions.keyAt(i));
ret.add(item);
}
}
return ret;
}
Very simple, use below code
listViewRequests.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
AppCompatCheckedTextView checkBox = (AppCompatCheckedTextView) view;
if (checkBox.isChecked() == true){
Log.i("CHECK",checkBox.isChecked()+""+checkBox.getText().toString());
}
}
});
for(int i =0; i< listView.getAdapter().getCount(); i++){
if(listView.isItemChecked(i)){
listView.getAdapter().getItem(i); // item
}
}
should be used after setAdapter() method