- Число столбцов должно быть не меньше 5 и не больше 25.
- Число строк должно быть не меньше 5 и не больше 35.
- Начальное количество клеток должно быть не больше, чем ячеек на поле.
Кроме того, мы добавим кнопку Close, при нажатии на которую приложение будет закрываться, спрашивая вначале согласие пользователя.
Простой диалог
Сначала добавим в классStartActivity.java
следующие константы:StartActivity.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;
StartActivity.java
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
), открывать окно RunActivity
, иначе же показывать предупреждение. Итак, onClick
будет выглядеть так:StartActivity.java
public void onClick(View v) { EditText rowsEditor = (EditText)findViewById(R.id.rows_count); EditText colsEditor = (EditText)findViewById(R.id.columns_count); EditText cellsEditor = (EditText)findViewById(R.id.cells_count); 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, RunActivity.class); intent.putExtra(RunActivity.EXT_COLS, cols); intent.putExtra(RunActivity.EXT_ROWS, rows); intent.putExtra(RunActivity.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
при этом нужно добавить следующие значения: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
, который ничего не делает (нам, в принципе, делать ничего и не надо). Аналогичным образом можно добавить иконку формы, добавить ещё кнопок и т.д.Подробнее про то, как строятся диалоги, можно посмотреть в адроидовских сэмплах - там на самом деле все достаточно понятно и просто.
Теперь при вводе некорректных данных мы видим вот это:
Диалог для закрытия приложения
Добавим на формуRunActivity
кнопку Close. Для этого напишем такую разметку в run.xml
: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/close" android:text="@string/close" android:textStyle="bold" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
strings.xml
добавим следующие значения: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>
RunActivity
:RunActivity.java
public class RunActivity extends Activity implements OnClickListener { 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.close); 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); } public void onClick(View view) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder .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) { } }) .show(); } }
При нажатии на Yes приложение закроется, на No — продолжит работу.
Исходники примера
Дарья, спасибо за полезные примеры!!
ОтветитьУдалитьу меня есть вопрос немножко off topic - как вам удается вставлять куски кода в blog. Я пробовал на blogspot.com - почему-то половину не видно ... пробовал pre тэги - не помогло. Буду признателен за совет. Спасибо!
У меня свой подсветчик синтаксиса. А в общем-то можно использовать любой существующий.
ОтветитьУдалитьЗдравствуйте, Дарья.
ОтветитьУдалитьНе могли бы Вы объяснить, зачем нам нужен обработчик doNothing?
Дарья, большое спасибо за статьи.
ОтветитьУдалитьНе могли бы вы внести конкретно в эту замечания, касательно того, в каких классах дополнительно что импортируется.
int cols=0;
ОтветитьУдалитьint rows=0;
int cells=0;
try {
cols = Integer.parseInt(colsEditor.getText().toString());
rows = Integer.parseInt(rowsEditor.getText().toString());
cells = Integer.parseInt(cellsEditor.getText().toString());
} catch (Exception e) {
}
Я бы добавил, а то совсем легко приложение падает. :)
Подскажите пожалуйста есть ли
ОтветитьУдалитьвозможность не закрывать приложение а вернутся к начальному окну приложения ?
2 Vik плохо читал предидущую статью - раз из первого окна во второе можно то и обратно так же) Только что проверил - работает.
ОтветитьУдалитьПри наводе курсором мышки на showDialog пишет:
ОтветитьУдалитьthis method is deprecated. Use the new DialogFragment class with FragmentManager instead. Думаю, стоит сделать update статьи.Но спасибо огромное за интересный материал, перехожу к 4-й части.
2 Vik я посто убрал finish() в первом окне, теперь при нажатии кнопки назад или кнопки Close переходит обратно
ОтветитьУдалить