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
Related
I am trying to show Ticks(green tick as in the screenshot) on comparing two ArrayList in a recyclerView.
The first ArrayList (List1) contains all the dates:
List1 = [2022-02-21,2022-02-22,2022-02-23 2022-02-24, 2022-02-25, 2022-03-10]
The second ArrayList (List2) contains only the dates which upon matching with List1 will enable the green tick:
List2 = [2022-02-21,2022-02-22]
This is how I am comparing it in my Adapter class :
for (int j = 0; j < List1.size(); j++) {
if (List1.get(j).trim().equalsIgnoreCase(List2.get(position).trim())) {
holder.greenTick.setVisibility(View.VISIBLE);
} else {
holder.greenTick.setVisibility(View.GONE);
}
}
The problem is that all the Ticks are visible. The matching of ArrayList is not working.
If you use List1 to show all the dates in the recycler, then position in your code is probably the adapter item position for each date square you got from List1.
You then want to compare each item with the values in List2 to know if you should show the tick or not.
So the comparison should be something like
for (int j = 0; j < List2.size(); j++) {
if ("Adapter item at position".equalsIgnoreCase(List2.get(j).trim())) {
holder.greenTick.setVisibility(View.VISIBLE);
} else {
holder.greenTick.setVisibility(View.GONE);
}
}
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 am using a multi select listview in my application. Specifically the simple_list_item_activated_1.
I have some of code, a button, that will select all the listview items. I have some logic saying that if all the items are already selected then deselect all the items.
When I press the button the first time, it will select all the items in the list as expected. and when I press the button a second time it deselects all the items as expected.
Here is my problem:
When I press the button for a third time "selectedCount" still equals "childCount". So obviously my code will never enter the If statement.
Would anyone know why this is happening? or maybe there is a better way to do what im trying to achieve?
int childCount = officerList.getChildCount();
int selectedCount = officerList.getCheckedItemPositions().size();
if(childCount != selectedCount){
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, true);
}
}else{
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, false);
}
}
}
Try this logic, it will check all the items if none of the items are checked, else will check only the items which are unchecked and vice versa.
public void onClick(View v) {
SparseBooleanArray sparseBooleanArray = officerList.getCheckedItemPositions();
if(sparseBooleanArray != null && sparseBooleanArray.size() >0) {
for (int index = 0; index < sparseBooleanArray.size(); index++) {
if(sparseBooleanArray.valueAt(index)){
officerList.setItemChecked(sparseBooleanArray.keyAt(index),true);
}
else {
officerList.setItemChecked(sparseBooleanArray.keyAt(index),false);
}
}
}
else {
for (int index = 0; index < officerList.getCount(); index++) {
officerList.setItemChecked(index,true);
}
}
}
I managed to answer my own question. Using getCheckItemPositions().size() is an unreliable way of achieving what I want.
This will return a sparseBooleanArray() of all Items checked, so the first time it works correctly as initially there is nothing selected so it will return 0. Then once everything is selected the sparseBooleanArray will be equal to all the items in the list as they were all selected.
However as I learned spareBooleanArray is an Array that stores the position and a Boolean flag of if it is selected or not. In my scenario when I press the select all button for the third, the size of the array is still equal to number of list items.
How I have fixed my issue, is to use getCheckedItemCount() which only returns the number of selected items as I originally wanted. hopefully this answer will help someone else.
int childCount = officerList.getChildCount();
int selectedCount = officerList.getCheckedItemCount();
if(childCount != selectedCount){
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, true);
}
}else{
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, false);
}
}
}
I have an array adapter(string), and would like to convert it to a List<String>, but after a little googling and a few attempts, I am no closer to figuring out how to do this.
I have tried the following;
for(int i = 0; i < adapter./*what?*/; i++){
//get each item and add it to the list
}
but this doesn't work because there appears to be no adapter.length or adapter.size() method or variable.
I then tried this type of for loop
for (String s: adapter){
//add s to the list
}
but adapter can't be used in a foreach loop.
Then I did some googling for a method (in Arrays) that converts from an adapter to a list, but found nothing.
What is the best way to do this? Is it even possible?
for(int i = 0; i < adapter.getCount(); i++){
String str = (String)adapter.getItem(i);
}
Try this
// Note to the clown who attempted to edit this code.
// this is an input parameter to this code.
ArrayAdapter blammo;
List<String> kapow = new LinkedList<String>(); // ArrayList if you prefer.
for (int index = 0; index < blammo.getCount(); ++index)
{
String value = (String)blammo.getItem(index);
// Option 2: String value = (blammo.getItem(index)).toString();
kapow.add(value);
}
// kapow is a List<String> that contains each element in the blammo ArrayAdapter.
Use option 2 if the elements of the ArrayAdapter are not Strings.
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;