Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning values from multiple selection ListView

Edit: Okay, I found a solution. Don't know that it's the proper solution, but it does work correctly. Added to the code below.

I'm trying to allow a user to select a number of directories from a checklist, and return them upon clicking a "Submit" button. Here's a snippet of my code. It populates the ListView with all the directories on /sdcard/, and for the initial selection (of however many I pick) when I submit, the log shows the correct choices returned. However, if I uncheck an item, and click "Submit" again, it still shows as if all are selected. Do I need to write a handler to uncheck an item? I thought that was taken care of by the choiceMode selection? Thanks!

private SparseBooleanArray a;    
directoryList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, directoryArray));
    submitButton = (Button)findViewById(R.id.submit_button);
    submitButton.setOnClickListener(new OnClickListener()
        {
        @Override
        public void onClick(View v)
        {
            a = new SparseBooleanArray();
            a.clear();
            a = directoryList.getCheckedItemPositions();

            for (int i = 0; i < a.size(); i++)
            {
                //added if statement to check for true. The SparseBooleanArray
                //seems to maintain the keys for the checked items, but it sets
                //the value to false. Adding a boolean check returns the correct result.                    
                if(a.valueAt(i) == true)
                    Log.v("Returned ", directoryArray[a.keyAt(i)]);

            }                
        }
    });
like image 709
Kevin Coppock Avatar asked Aug 12 '10 03:08

Kevin Coppock


4 Answers

Did some more debugging and found a solution that worked for me. Edited into code above. For some reason, the SparseBooleanArray doesn't empty itself; it maintains the keys of the boxes that have been checked. When getCheckedItemPositions() is called, however, it sets the VALUE to false. So the key is still in the returned array, but it has a value of false. Only the checked boxes will be marked with a value of true.

like image 111
Kevin Coppock Avatar answered Nov 13 '22 05:11

Kevin Coppock


I know you found a solution that works for you, but the cleaner and simpler solution that will probably work most of the time is this (I want to persist all the ids of the elements selected):

(in my ListActivity):

SparseBooleanArray selectedPos = getListView()
        .getCheckedItemPositions();

ListAdapter lAdapter = getListAdapter();
List<Long> ids = new ArrayList<Long>();
for (int i = 0; i < lAdapter.getCount(); i++) {
    if (selectedPos.get(i)) {
        ids.add(lAdapter.getItemId(i));
    }
}
like image 20
ansjob Avatar answered Nov 13 '22 04:11

ansjob


didn't mean to do this as an answer but i had to expand on what you did to do multi select. Why did you do a field variable for your selections? i just did local SparseBooleanArray...

public class NaughtyAndNice extends ListActivity {
TextView selection;
String[] items={"lorem","ipsum", "dolor", "sit", "amet",
        "consectetuer", "adipisc", "jklfe", "morbi", "vel",
        "ligula", "vitae", "carcu", "aliequet"};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice,items));
           selection = (TextView)findViewById(R.id.selection);
    this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}

public void onListItemClick(ListView parent, View view, int position, long id){
    SparseBooleanArray choices = parent.getCheckedItemPositions();
    StringBuilder choicesString = new StringBuilder();
    for (int i = 0; i < choices.size(); i++)
    {
    //added if statement to check for true. The SparseBooleanArray
    //seems to maintain the keys for the checked items, but it sets
    //the value to false. Adding a boolean check returns the correct result.                    
        if(choices.valueAt(i) == true)
            choicesString.append(items[choices.keyAt(i)]).append(" ");

    } 
    selection.setText(choicesString);
}
}

like image 1
JDPeckham Avatar answered Nov 13 '22 03:11

JDPeckham


No need to use SparseBooleanArray choices = parent.getCheckedItemPositions();

StringBuilder is enough for this.

like image 1
nipun Avatar answered Nov 13 '22 04:11

nipun