воскресенье, 26 октября 2008 г.

Знакомство с Android. Часть 3: Использование диалогов

Somethings: Знакомство с Android. Часть 3: Использование диалогов

В этой части мы сделаем проверку вводимых параметров по следующим правилам:

  • Число столбцов должно быть не меньше 5 и не больше 25.
  • Число строк должно быть не меньше 5 и не больше 35.
  • Начальное количество клеток должно быть не больше, чем ячеек на поле.

Если какое-то из этих условий не выполняется, будем выводить соответствующее предупреждение

Кроме того, мы добавим кнопку Close, при нажатии на которую приложение будет закрываться, спрашивая вначале согласие пользователя.

Простой диалог

Сначала добавим в класс StartScreen.java следующие константы:
// код результата проверки private static final int ALERT_NONE = 0; // параметры введены верно private static final int ALERT_COLUMNS = 1; // некорректное число столбцов private static final int ALERT_ROWS = 2; // некорректное число строк private static final int ALERT_CELLS = 3; // некорректное начальное число клеток  // границы допустимых значений числа столбцов private static final int COLUMNS_MIN = 5; private static final int COLUMNS_MAX = 25;  // границы допустимых значений числа строк private static final int ROWS_MIN = 5; private static final int ROWS_MAX = 35; 

Теперь добавляем метод, осуществляющий проверку введенных параметров:

private int checkInputParameters(int cols, int rows, int cells) {   if (cols < COLUMNS_MIN || cols > COLUMNS_MAX)   {     return ALERT_COLUMNS;   }      if (rows < ROWS_MIN || rows > ROWS_MAX)   {     return ALERT_ROWS;   }      if (cells > rows * cols)   {     return ALERT_CELLS;   }      return ALERT_NONE; } 

Метод onClick теперь должен работать немного по-другому: сначала проверять введенные параметры, и, если проверка прошла (ALERT_NONE), открывать окно RunScreen, иначе же показывать предупреждение. Итак, onClick будет выглядеть так:

public void onClick(View v) {   EditText rowsEditor = (EditText)findViewById(R.id.RowsEditor);   EditText colsEditor = (EditText)findViewById(R.id.ColumnsEditor);   EditText cellsEditor = (EditText)findViewById(R.id.CellsEditor);      int cols = Integer.parseInt(colsEditor.getText().toString());   int rows = Integer.parseInt(rowsEditor.getText().toString());   int cells = Integer.parseInt(cellsEditor.getText().toString()); 

  int alertCode = checkInputParameters(cols, rows, cells);   if (alertCode != ALERT_NONE)   {     showDialog(alertCode);     return;   }

  Intent intent = new Intent();   intent.setClass(this, RunScreen.class);      intent.putExtra(RunScreen.EXT_COLS, cols);   intent.putExtra(RunScreen.EXT_ROWS, rows);   intent.putExtra(RunScreen.EXT_CELLS, cells);   startActivity(intent);   finish(); }

Метод showDialog(id) класса Activity пытается открыть диалог. При этом вызывается метод onCreateDialog, возвращающий объект класса Dialog. Так что нужно перекрыть метод onCreateDialog и сконструировать тот диалог, который нам нужен. Ну у нас тут всё просто, диалоги будут отличаться только выводимым сообщением, так что можно сделать следующее:

@Override protected Dialog onCreateDialog(int id) {   DialogInterface.OnClickListener doNothing = new DialogInterface.OnClickListener()   {     public void onClick(DialogInterface dialog, int whichButton)     {     }   };   int alertMessage;      switch (id)   {     case ALERT_COLUMNS:       alertMessage = R.string.alert_columns;       break;     case ALERT_ROWS:       alertMessage = R.string.alert_rows;       break;     case ALERT_CELLS:       alertMessage = R.string.alert_cells;       break;     default:       return null;   }      return new AlertDialog.Builder(this)     .setMessage(alertMessage)     .setNeutralButton(R.string.ok, doNothing)     .create(); } 

В strings.xml при этом нужно добавить следующие значения:

<string name="alert_columns">Incorrect columns number: should be from 5 to 25</string> <string name="alert_rows">Incorrect rows number: should be from 5 to 35</string> <string name="alert_cells">Number of cells is greater then the size of grid</string> <string name="ok">OK</string> 

Итак, в методе onCreateDialog мы решили, какое сообщение (alertMessage) будем выводить, создали диалог с помощью AlertDialog.Builder, вывели туда сообщение, поставили единственную кнопку OK и привязали к ней обработчик doNothing, который ничего не делает (нам, в принципе, делать ничего и не надо). Аналогичным образом можно добавить иконку формы, добавить ещё кнопок и т.д.

Подробнее про то, как строятся диалоги, можно посмотреть в адроидовских сэмплах - там на самом деле все достаточно понятно и просто.

Теперь при вводе некорректных данных мы видим вот это:

Простейший диалог Android

Диалог для закрытия приложения

Добавим на форму RunScreen кнопку Close. Для этого напишем такую разметку в run.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent">   <TextView     android:id="@+id/Message"     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:paddingBottom="10dip"   />   <Button     android:id="@+id/CloseButton"     android:text="@string/close"     android:textStyle="bold"     android:layout_width="wrap_content"     android:layout_height="wrap_content"   /> </LinearLayout> 

В strings.xml добавим следующие значения:

<string name="yes">yes</string> <string name="no">no</string> <string name="close">Close</string> <string name="submit_close">Are you sure you want to close this wonderful application?</string> 

Теперь вносим изменения в класс RunScreen:

public class RunScreen extends Activity implements OnClickListener { 

  private static final int ALERT_CLOSE = 1;   public static final String EXT_COLS = "cols";   public static final String EXT_ROWS = "rows";   public static final String EXT_CELLS = "cells";   

  Button mCloseButton;

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

    mCloseButton = (Button) findViewById(R.id.CloseButton);     mCloseButton.setOnClickListener(this);

    Bundle extras = getIntent().getExtras();     int cols = extras.getInt(EXT_COLS);     int rows = extras.getInt(EXT_ROWS);     int cells = extras.getInt(EXT_CELLS);     TextView message = (TextView)findViewById(R.id.Message);     message.setText("Rows: " + rows + "\nColumns: " + cols + "\nCells: " + cells);   }

  /*   * @see android.view.View.OnClickListener#onClick(android.view.View)   */   @Override   public void onClick(View arg0)   {     showDialog(ALERT_CLOSE);   }

  @Override   protected Dialog onCreateDialog(int id)   {     switch (id)     {       case ALERT_CLOSE:         return new AlertDialog.Builder(this)         .setMessage(R.string.submit_close)         // кнопка "Yes", при нажатии на которую приложение закроется         .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()           {             public void onClick(DialogInterface dialog, int whichButton)             {               finish();             }           })         // кнопка "No", при нажатии на которую ничего не произойдет         .setNegativeButton(R.string.no, new DialogInterface.OnClickListener()           {             public void onClick(DialogInterface dialog, int whichButton)             {                            }           })         .create();       default:         break;     }     return null;   }

}

Объяснять тут особо нечего, и так все понятно. Теперь, при нажатии на кнопку Close, мы видим следующее:

Диалог Android

При нажатии на yes приложение закроется, на no - продолжит работу.

Ссылки

Исходники примера

Комментариев нет: