Lesson 64. Dialogues. AlertDialog. Multiple choice list

Lesson 64. Dialogues. AlertDialog. Multiple choice list


In this lesson:

– form a list with multiple choices in the dialog

The lesson will be similar to the past. We will form a multiple-choice list in the dialog and determine which items have been selected (checked). This time we will only be able to work with an array and cursor. The adapter will fail to give a dialog, there is no appropriate method. These are the features of the implementation.

Let’s create a project:

Project name: P0641_AlertDialogItemsMulti
Build Target: Android 2.3.3
Application name: AlertDialogItemsMulti
Package name: en.startandroid.develop.p0641alertdialogitemsmulti
Create Activity: MainActivity

IN strings.xml write down the texts:



    AlertDialogItemsMulti
    Items
    Cursor
    OK

main.xml:



    
    

DB.java:

package ru.startandroid.develop.p0641alertdialogitemsmulti;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DB {
  
  private static final String DB_NAME = "mydb";
  private static final int DB_VERSION = 1;
  private static final String DB_TABLE = "mytab";
  
  public static final String COLUMN_ID = "_id";
  public static final String COLUMN_CHK = "checked";
  public static final String COLUMN_TXT = "txt";
  
  private static final String DB_CREATE = 
    "create table " + DB_TABLE + "(" +
      COLUMN_ID + " integer primary key, " +
      COLUMN_CHK + " integer, " +
      COLUMN_TXT + " text" +
    ");";
  
  private final Context mCtx;
  
  
  private DBHelper mDBHelper;
  private SQLiteDatabase mDB;
  
  public DB(Context ctx) {
    mCtx = ctx;
  }
  
  // открыть подключение
  public void open() {
    mDBHelper = new DBHelper(mCtx, DB_NAME, null, DB_VERSION);
    mDB = mDBHelper.getWritableDatabase();
  }
  
  // закрыть подключение
  public void close() {
    if (mDBHelper!=null) mDBHelper.close();
  }
  
  // получить все данные из таблицы DB_TABLE
  public Cursor getAllData() {
    return mDB.query(DB_TABLE, null, null, null, null, null, null);
  }
  
  //изменить запись в DB_TABLE
  public void changeRec(int pos, boolean isChecked) {
      ContentValues cv = new ContentValues();
      cv.put(COLUMN_CHK, (isChecked) ? 1 : 0);
      mDB.update(DB_TABLE, cv, COLUMN_ID + " = " + (pos + 1), null);
  }
  
  // класс по созданию и управлению БД
  private class DBHelper extends SQLiteOpenHelper {

    public DBHelper(Context context, String name, CursorFactory factory,
        int version) {
      super(context, name, factory, version);
    }

    // создаем и заполняем БД
    @Override
    public void onCreate(SQLiteDatabase db) {
      db.execSQL(DB_CREATE);
      
      ContentValues cv = new ContentValues();
      for (int i = 1; i < 5; i++) {
      cv.put(COLUMN_ID, i);
      cv.put(COLUMN_TXT, "sometext " + i);
      cv.put(COLUMN_CHK, 0);
      db.insert(DB_TABLE, null, cv);
      }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
  }
}

We create a numeric field in the table checked. In this field, the dialog list will determine the highlighted element (value = 1) or not (0). method changeRec takes the position of the item in the list and boolean values, selects the item or not, and changes the corresponding entry in the table.

MainActivity.java:

package ru.startandroid.develop.p0641alertdialogitemsmulti;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";
  
  final int DIALOG_ITEMS = 1;
  final int DIALOG_CURSOR = 3;
  DB db;
  Cursor cursor;

  String data[] = { "one", "two", "three", "four" };
  boolean chkd[] = { false, true, true, false };

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // открываем подключение к БД
    db = new DB(this);
    db.open();
    cursor = db.getAllData();
    startManagingCursor(cursor);
  }

  public void onclick(View v) {
    switch (v.getId()) {
    case R.id.btnItems:
      showDialog(DIALOG_ITEMS);
      break;
    case R.id.btnCursor:
      showDialog(DIALOG_CURSOR);
      break;
    default:
      break;
    }
  }

  protected Dialog onCreateDialog(int id) {
    AlertDialog.Builder adb = new AlertDialog.Builder(this);
    switch (id) {
    // массив
    case DIALOG_ITEMS:
      adb.setTitle(R.string.items);
      adb.setMultiChoiceItems(data, chkd, myItemsMultiClickListener);
      break;
    // курсор
    case DIALOG_CURSOR:
      adb.setTitle(R.string.cursor);
      adb.setMultiChoiceItems(cursor, DB.COLUMN_CHK, DB.COLUMN_TXT, myCursorMultiClickListener);
      break;
    }
    adb.setPositiveButton(R.string.ok, myBtnClickListener);
    return adb.create();
  }

  // обработчик для списка массива
  OnMultiChoiceClickListener myItemsMultiClickListener = new OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
      Log.d(LOG_TAG, "which = " + which + ", isChecked = " + isChecked);
    }
  };  
  
  // обработчик для списка курсора
  OnMultiChoiceClickListener myCursorMultiClickListener = new OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
      ListView lv = ((AlertDialog) dialog).getListView();
      Log.d(LOG_TAG, "which = " + which + ", isChecked = " + isChecked);
      db.changeRec(which, isChecked);
      cursor.requery();
    }
  };
  
  // обработчик нажатия на кнопку
  OnClickListener myBtnClickListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        SparseBooleanArray sbArray = ((AlertDialog)dialog).getListView().getCheckedItemPositions();
        for (int i = 0; i < sbArray.size(); i++) {
          int key = sbArray.keyAt(i);
          if (sbArray.get(key))
            Log.d("qwe", "checked: " + key);
        }    
    }
  };

  protected void onDestroy() {
    super.onDestroy();
    db.close();
  }

}

Let's parse the code. In addition to the array of rows given, We need a boolean array[] chkdWhich will indicate to the dialog what elements of the list should be highlighted immediately. We will highlight the second and third.

IN onCreate we connect to the base.

onclick - depending on the button pressed, we call the appropriate dialog.

onCreateDialog - create a dialog called using AlertDialog.Builder. The dialog can construct a list using one of the following objects:

1) massif rows. The setMultiChoiceItems method is used. An input is given an array of rows, a boolean array that defines the highlighted elements, and a click handler.

2) cursor DB. Call the setMultiChoiceItems method. We send the cursor, the name of the selection field (information about the selection of the list items), the name of the text field (the text that will be displayed in the list) and the click handler.

In addition to the list, we specify only the title. Finally add the OK button, create and return the Dialog.

Both create methods use methods with the same name setMultiChoiceItems, but with different input arguments.

myItemsMultiClickListener - list click handler built from an array. Displays which element was clicked and became highlighted or unselected. Implements the OnMultiChoiceClickListener interface.

myCursorMultiClickListener - Click list handler built from the cursor. Displays which element was clicked and became highlighted or unselected. It also modifies the data in the database accordingly and updates the cursor of the dialog list. Because if an item is selected, we have to override the database in the handler, update the corresponding entry (checked field) and update the cursor. For the sake of interest comment on the code of this handler - you will see that the ticks in the list simply do not fit.

myBtnClickListener - button handler. Retrieves selected item information from the list and logs it.

IN onDestroy close the connection to the database.

We'll save everything and run it. Open the Items dialog.

We see that the hooks are put down as we indicated in the chkd array. If you click on the items in the list, the log shows you what changes are happening.

which = 1, isChecked = false
which = 0, isChecked = true
which = 3, isChecked = true

If necessary, you can add code to the handler that would update the chkd array according to the clicks. The element index and value we have.

Open the Cursor dialog. Nothing is highlighted here because we checked zeros in the checked field.

Let's put down the pegs,

the log will display this

which = 1, isChecked = true
which = 3, isChecked = true

This only works because we manually update the database and cursor. Again, try commenting on the myCursorMultiClickListener handler code and the items will stop highlighting.

I did not implement the method onPrepareDialog. In the case of Items, everything is simple there, similar to the previous lesson, use the following code:

((AlertDialog) dialog) .getListView (). SetItemChecked (2, true);

In this example: 2 is the position of the list item, and true means that the pebble must stand. If you want to remove the pebble, pass false.

In the case of the cursor, the code will be similar to the code from the handler myCursorMultiClickListener. You change the entry in the database by the method db.changeRec, Upgrade the cursor and pass it to the adapter.

This is a nontrivial thing, I do not know whether someone will need it or not, but if I have already started the dialogs - I decided to paint it too.

It also probably makes sense to say that the setItems, setSingleChoiceItems, setMultiChoiceItems methods also have an implementation that does not use the array array from the resource file directly, not directly.

In the next lesson:

- we use our View to build a dialogue




Discuss in the forum [13 replies]

Leave a Comment