2

I created an AlertDialog that has a ListView of items along with check boxes. I want to be able to collect the checked items in the calling activity so that I can use them.

I have a button in my activity:

<Button android:id="@+id/my_button" />

That I get like so:

Button button = (Button)findViewById(R.id.my_button);

Then I set a listener:

button.setOnClickListener(my_on_click_listener);
View.OnClickListener my_on_click_listener = new View.OnClickListener(){
    @Override
    public void onClick(View v){
        my_method();
    }
};

That calls a method:

public void my_method(){
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
    LayoutInflater layoutInflater = this.getLayoutInflater();
    View view = layoutInflater.inflate(R.layout.my_listview_layout, null);
    dialogBuilder.setView(view);

    final DatabaseHelper databaseHelper = new DatabaseHelper(this);
    String[] fromColumns = {"_id","value"};
    int[] toViews = {R.id.dropdown_id, R.id.dropdown_value};

    final ListView listView = (ListView)view.findViewById(R.id.my_listview);

    final Cursor cursor = databaseHelper.getData();
    SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this, R.layout.my_layout, cursor, fromColumns, toViews, 0);
    listView.setAdapter(simpleCursorAdapter);

    // I tried this, but I'm not sure what to use for the isCheckedColumn and labelColumn
    dialogBuilder.setMultiChoiceItems(cursor, "", "", new DialogBuilder.OnMultiChoiceClickListener(){
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked){
            // do stuff here ...
        }
    });

    dialogBuilder.setPositiveButton("Save Selected", new DialogInterface.OnClickListener(){
        public void onClick(DialogInterface dialog, int which){
            // I tried this, but it only collects the elements within view
            for(int i=0; i<listView.getCount(); i++){
                LinearLayout ll = (LinearLayout)listView.getChildAt($i);
                if(null != ll){
                    CheckBox cb = (CheckBox)ll.findViewById(R.id.dropdown_checkbox);
                    TextView tv01 = (CheckBox)ll.findViewById(R.id.dropdown_id);
                    TextView tv02 = (CheckBox)ll.findViewById(R.id.dropdown_value);
                }
            }
        }
    });

    final AlertDialog alert = dialogBuilder.create();
    alert.setTitle("Select Choices");
    alert.show();
}

Here is my_listview_layout.xml:

<ListView android:id="@+id/my_listview" />

Here is my_layout.xml:

<LinearLayout>
    <CheckBox android:id="@+id/dropdown_checkbox" />
    <TextView android:id="@+id/dropdown_value" />
    <TextView android:id="@+id/dropdown_id" android:visibility="invidible"/>
</LinearLayout>

See my two comments in the code above.

So, how can I get my checked values from a ListView populated by a cursor within an AlertDialog in Android?

----

UPDATE:

Within my code, I commented out this line:

listView.setAdapter(simpleCursorAdapter);

and changed this line:

dialogBuilder.setMultiChoiceItems(cursor, "", "", new DialogBuilder.OnMultiChoiceClickListener();

to this:

dialogBuilder.setMultiChoiceItems(cursor, "_id", "value", new DialogBuilder.OnMultiChoiceClickListener()

and now my dialog is rendering properly, and I can determine which items are checked. I guess [maybe] both the ListView and setMultiChoiceItems() were fighting for control over drawing the list of choices.

However, I have a new issue. if I check some items at the top of the list, then scroll down and back up, the items I checked have been unchecked. That, and the first item in the list is checked by default and I cannot figure out how to uncheck it.

Any ideas???

Thanks ... again.

Brian
  • 1,726
  • 2
  • 24
  • 62
  • are you able to get any callback in `dialogBuilder.setMultiChoiceItems(cursor, "", "", new DialogBuilder.OnMultiChoiceClickListener(){ @Override public void onClick(DialogInterface dialog, int which, boolean isChecked){ // do stuff here ... } });` even if you send empty string in parameters? – karandeep singh Jan 08 '18 at 20:22
  • I get a `java.lang.IllegalArgumentException: column '' does not exist`. – Brian Jan 08 '18 at 20:39
  • You can pass one of the column name in that and try how it works. After that you can anyway get the callback in the listener. – karandeep singh Jan 08 '18 at 20:42
  • I tried `_id` and `value` but my positive button (as in `setPositiveButton`) disappears. – Brian Jan 08 '18 at 20:51
  • I'll try and get back to you this on tomorrow. – karandeep singh Jan 08 '18 at 20:55

2 Answers2

3

You can do something like this:

// Fetch the list of items from any of your sources and store it as an array list.
// Here I'm considering itemList as the source it is a string array but you
   can use an array list rather.

    final ArrayList<String> selectedItemList = new ArrayList<>();
    final int itemListLength = itemList.length;
    final boolean[] selectionPreference = new boolean[itemListLength];

    for(int i=0; i < itemListLength; i++){
        Arrays.fill(selectionPreference, Boolean.FALSE);
    }

    AlertDialog.Builder builder =  new AlertDialog.Builder(context);

    builder.setTitle("Select one")
            .setMultiChoiceItems(itemList, selectionPreference, 
     new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                    String item = itemList[which];
                    if(isChecked){
                        selectionPreference[which] = true;
                    } else {
                        selectionPreference[which] = false;
                    }
                }
            })
    .setPositiveButton("ok",new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            for (int i=0; i<itemListLength; i++) {
                if(selectionPreference[i]) {
                    selectedItemList.add(itemList[i]);
                }
            }
            Log.i(TAG, String.valueOf(selectedItemList));
        }
    }).show();

The process that you have used might be a bit tedious. So, use this way it'll be easy to access and retain values. Hope that it'll be helpful.

Akshay
  • 161
  • 7
-1

Check this solution https://stackoverflow.com/a/31315985/2610010

First Create a custom ArrayList and add all your items in custom ArrayList

Set your boolean in your adapter on CheckBox click

holder.checkBox.setChecked(actorList.get(position).isSelected());

holder.checkBox.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        boolean isSelected = ((CheckBox)v).isChecked();
        actorList.get(position).setSelected(isSelected);
    }
});

and on Click of your button use following code

 btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ArrayList<Service> actorList = ((ServiceAdapter)listView.getAdapter()).getSelectActorList();
        Toast.makeText(MainActivity.this,""+actorList.size(),Toast.LENGTH_LONG).show();
    }
});
Ameer
  • 2,709
  • 1
  • 28
  • 44
  • It can't be an array list ... I need to pull the values from the database; it needs to be a cursor. – Brian Jan 09 '18 at 14:49
  • You can save values from database to arraylist. Something like this will help you. notificationsModelClassArrayList = new ArrayList<>(); NotificationsModelClass listRowItem = new NotificationsModelClass(cursor.getString(cursor.getColumnIndex(DatabaseHelper.Msg_Title)), cursor.getString(cursor.getColumnIndex(DatabaseHelper.Msg_Read_Status)))); notificationsModelClassArrayList.add(listRowItem); – Ameer Jan 11 '18 at 05:26