Lesson 62. Dialogues. AlertDialog. list
Android Lessons

Lesson 62. Dialogues. AlertDialog. list


In this lesson:

– form a list in the dialog

Some of the methods used in the lesson are outdated. After reading it, I recommend reading the current topics by topic:
– creating dialogues using snippets (Lessons 104-105,110)
– working with the cursor through a loader (lessons 135-136)

It is possible to deduce in dialogue not only text, But also list values. Dialog can be three types:

– without selecting items
– with a single choice
– with multiple choice

In this lesson, let’s look at the first look.

Let’s learn how to create a dialog with a list using massif data, adapter or cursor. In addition to creating, we will try to modify the data and update the list before each impression. To do this, enter the Impression Meter and display it in the last line of the list. Each call to the list will increase the counter by one and this should be reflected in the list. So we will make sure that it is updated.

let’s create project:

Project name: P0621_AlertDialogItems
Build Target: Android 2.3.3
Application name: AlertDialogItems
Package name: ru.startandroid.develop.p0621alertdialogitems
Create Activity: MainActivity

IN strings.xml write down the texts:



    AlertDialogItems
    Items
    Adapter
    Cursor

On the screen main.xml three buttons:



    
    
    

To work with the database, select a separate class DB.java:

package ru.startandroid.develop.p0621alertdialogitems;

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_TXT = "txt";
  
  private static final String DB_CREATE = 
    "create table " + DB_TABLE + "(" +
      COLUMN_ID + " integer primary key, " +
      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 id, String txt) {
    ContentValues cv = new ContentValues();
    cv.put(COLUMN_TXT, txt);
    mDB.update(DB_TABLE, cv, COLUMN_ID + " = " + id, 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);
        db.insert(DB_TABLE, null, cv);
      }
    }

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

Everything is as usual here. Methods to open and close a connection, retrieve a cursor with data, and change the entry by ID. A table of just two fields - _id and txt. At creation we insert in table 4 records.

MainActivity.java:

package ru.startandroid.develop.p0621alertdialogitems;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.CursorAdapter;
import android.widget.ListAdapter;

public class MainActivity extends Activity {

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

  String data[] = { "one", "two", "three", "four" };

  /** 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) {
    changeCount();
    switch (v.getId()) {
    case R.id.btnItems:
      showDialog(DIALOG_ITEMS);
      break;
    case R.id.btnAdapter:
      showDialog(DIALOG_ADAPTER);
      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.setItems(data, myClickListener);
      break;
    // адаптер
    case DIALOG_ADAPTER:
      adb.setTitle(R.string.adapter);
      ArrayAdapter adapter = new ArrayAdapter(this,
          android.R.layout.select_dialog_item, data);
      adb.setAdapter(adapter, myClickListener);
      break;
    // курсор
    case DIALOG_CURSOR:
      adb.setTitle(R.string.cursor);
      adb.setCursor(cursor, myClickListener, DB.COLUMN_TXT);
      break;
    }
    return adb.create();
  }

  protected void onPrepareDialog(int id, Dialog dialog) {
    // получаем доступ к адаптеру списка диалога
    AlertDialog aDialog = (AlertDialog) dialog;
    ListAdapter lAdapter = aDialog.getListView().getAdapter();
 
    switch (id) {
    case DIALOG_ITEMS:
    case DIALOG_ADAPTER:
      // проверка возможности преобразования
      if (lAdapter instanceof BaseAdapter) {
        // преобразование и вызов метода-уведомления о новых данных
        BaseAdapter bAdapter = (BaseAdapter) lAdapter;
        bAdapter.notifyDataSetChanged();
      }
      break;
    case DIALOG_CURSOR:
      break;
    default:
      break;
    }
  };

  // обработчик нажатия на пункт списка диалога
  OnClickListener myClickListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
      // выводим в лог позицию нажатого элемента
      Log.d(LOG_TAG, "which = " + which);
    }
  };

  // меняем значение счетчика 
  void changeCount() {
    cnt++;
    // обновляем массив
    data[3] = String.valueOf(cnt);
    // обновляем БД
    db.changeRec(4, String.valueOf(cnt));
    cursor.requery();
  }

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

given - an array of 4 elements. In the table with DB.java we also have 4 records. We decided to change the last (fourth) item / record in the data and put the number of impressions there.

IN onCreate we connect to the base.

onclick - change the value of the counter and adjust the data of the array and the database, and depending on the button pressed, we call the appropriate dialog.

onCreateDialog - create a dialog called using AlertDialog.Builder. Dialogue can build listUsing one of the following objects:

1) massif rows. The setItems method is used. An input and a click handler are fed to the input.

2) adapter. We create an ArrayAdapter using an array given and standard layout select_dialog_item, And pass it to the setAdapter method. We also send a handler there.

3) cursor DB. We call the setCursor method. Pass the cursor, the click handler, and the name of the field whose value will be displayed in the list.

In addition to the list, we specify only the title. Buttons and icons are not added. At the end, we create and return Dialog.

The dialog creation method (onCreateDialog) is executed once to create a dialog. Subsequent dialogues show a method onPrepareDialog. In it, we will update the list data. Using the getListView and getAdapter transforms and methods, we get a list from the dialog and then an adapter from the list.

Next, for dialogs that use an array and an adapter, we convert to BaseAdapter to call notifyDataSetChanged. This method updates the list to match the new data.

There is no need to notify the adapter of new data for dialog with the cursor. The cursor does this on its own.

myClickListener - Click list item handler. It is common for all dialogs and simply displays the position of the clicked item in the log.

IN changeCount increase the counter by one and write this value in the fourth element of the array (numbering from zero) and in a line with _id = 4 in the database. We are updating the cursor.

IN onDestroy close the connection to the database.

We'll save everything and run it. We promote dialogs and make sure that the data in them is updated at every impression.

Clicking on a list item activates the handler, logs its position and closes the dialog.

If we didn't implement the method onPrepareDialog, Then the lists of dialogs (except cursors) are not updated and displayed in the last line those values ​​of the counter at which they were created in the method onCreateDialog. Try commenting on the content of onPrepareDialog and make sure.

UPD from 11.07.2012. Protest this lesson on Android 3.2 - The data is updated without the onPrepareDialog.

In the next lesson:

- form a list with a single choice in the dialog




Discuss in the forum [29 replies]

Leave a Reply

Your email address will not be published. Required fields are marked *