Главная » Разработка для Android » ПОСТРОЕНИЕ ФОРМ ДЛЯ СБОРА ВВОДИМЫХ ПОЛЬЗОВАТЕЛЕМ ДАННЫХ – ЧАСТЬ 2

0

Внутрь элемента-контейнера LinearLayout добавьте элемент TextView, который будет использоваться для отображения названия параметра Nickname (Ник). Под элементом TextView с названием параметра расположите элемент EditText. Присвойте его атрибуту id значение EditText_Nickname, атрибуту maxLength — значение 2 0, атрибуту maxLines — значение 1, а атрибуту inputType — значение textPersonName.

Добавьте элемент TextView, который будет использоваться для отображения названия параметра Email. Под этим элементом расположите еще один элемент EditText, присвоив его атрибуту id значение EditText_Email, атрибуту maxLines — значение 1, а атрибуту inputType — значение textEmailAddress.

Добавьте область для параметра Password (Пароль), включив в макет еще один элемент TextVi ew, который будет использоваться для отображения названия данного параметра. Под добавленным элементом добавьте элемент-контейнер LinearLayout с горизонтальной ориентацией, включив в него два дополнительных элемента: элемент Button и элемент TextView. Присвойте атрибуту id элемента Button значение Button_Password, а атрибуту text присвойте строковый ресурс с названием кнопки Password (Пароль). Настройте элемент TextView таким образом, чтобы он исполь­зовался для отображения строки состояния параметра Password (Пароль) (на данный момент, это строка Password not set).

На том же уровне вложенности, на котором находится область для параметра Password (Пароль), добавьте область для параметра Date of Birth (Дата рождении). Сначала добавьте еще один элемент-контейнер будет использоваться для отображения названия параметра Date of Birth (Дата рождения). Затем добавьте еще один элемент-контейнер LinearLayout с горизонтальной ориентацией, включив в но дополнительных элемента: элемент Button и элемент TextView. Присвойте атрибуту id элемента управлении Button значение Button_DOB, а атрибуту text присвойте строковый ресурс с названием кнопки Date of Birth (Дата рождения). Настройте элемент TextView таким образом, чтобы он использовался для отображения строки состояния параметра Date of Birth (Дата рождения) (на данный момент, это строка Date not set).

Добавьте последнюю область для параметра Gender (Пол), включив элемент TextView, который будет использоваться для отображения названия параметра Gender (Пол). Затем добавьте элемент Spinner и присвойте его атрибуту id значение Spinner_Gender.

Перед тем, как сохранить внесенные изменения, настройте размеры шрифтов, гарнитуры, цвета, высоту и ширину элементов, чтобы добиться желаемого вида экрана.

Сохраните файл макета settings.xml.

ИСПОЛЬЗОВАНИЕ СТАНДАРТНЫХ ЭЛЕМЕНТОВ ФОРМ

Теперь, когда файл макета settings.xml готов, вам понадобится обновить класс QuizSettingsActivity, чтобы заполнить элементы макета данными и позволить пользователю редактировать и сохранять введенные значения. В этом разделе вы узнаете, как сохранять и восстанавливать данные формы.

Работа с элементами EditText

Элемент EditText, который наследуется от элемента TextView. применяется для сбора текстовых данных, вводимых пользователем. На рис. 10.3 изображен простой элемент EditText.

Рис. 10.3. Элемент EditText для ввода текстовых данных НАСТРОЙКА ЭЛЕМЕНТОВ EDITTEXT

Все атрибуты, присущие элементу TextView (например, атрибуты textColor и textSize), доступны и в элементах EditText. Ниже представлен список некоторых атрибутов элемента EditText, которые применяются на экране с настройками.

•     inputType. Информирует операционную систему Android о том, каким образом можно помочь пользователю ввести значение в данное поле ввода. Например, атрибуту inputType элемента EditText, связанного с параметром Email, вы присвоили значение textEmailAddress, которое указывает системе Android использовать программную клавиатуру, ориентированную на ввод адресов электронной почты (с символом @). Значение textPassword атрибута inputType позволяет автоматически скрывать пароль, вводимый пользователем.

•     minLines и maxLines. Позволяют ограничить количество строк текста, которое можно ввести в данном элементе.

•     maxLength. Ограничивает количество символов, которое можно ввести в данном элементе. Например, вы можете ограничить количество символов для параметра Nickname (Ник), указав для атрибута maxLength элемента EditText, связанного с этим параметром, значение 2 0.

ОБРАБОТКА ВВЕДЕННОГО ТЕКСТА

Как и в случае с элементом TextView, вы можете обращаться к тексту, хранящемуся в элементе EditText, при помощи методов getText () и setText () . Например, чтобы получить строку, введенную в элемент EditText с именем EditText_Nickname, можно использовать метод getText(), как показано в следующем коде:

EditText nicknameText = (EditText) findViewById(R.id.EditText_Nickname);

String strNicknameToSave = nicknameText.getText().toString();

Метод getText () возвращает объект типа Editable, однако в данном случае вы просто хотите получить его строковый эквивалент.

СОХРАНЕНИЕ ДАННЫХ, ВВЕДЕННЫХ В ЭЛЕМЕНТ EDITTEXT

Для обработки данных, введенных в элемент EditText, вы должны определить момент ввода нового текста. Для этого вы можете прослушивать события нажатий клавиш для элемента EditText и сохранять введенный текст, если были нажаты определенные клавиши. Например, для прослушивания события нажатия клавиши Enter в процессе ввода значения параметра Nickname (Ник) вы могли бы зарегистрировать обработчик View. OnKeyListener, используя метод setOnKeyListener () элемента EditText, как показано в следующем коде:

final EditText nicknameText =

(EditText) findViewById(R.id.EditText_Nickname); nicknameText.setOnKeyListener(new View.OnKeyListener() {

public boolean onKey(View v, int keyCode, KeyEvent event) { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { String strNicknameToSave = nicknameText.getText().toString();

// TODO: Save Nickname setting (strNicknameToSave) return true;

}

return false;

}

});

ПРОСЛУШИВАНИЕ СОБЫТИЙ НАЖАТИЯ КЛАВИШ ДЛЯ ЭЛЕМЕНТА EDITTEXT

Скоро вы займетесь разработкой диалогового окна для ввода пароля. Представим, что в процессе ввода данных пользователем вы хотите проверять на совпадение строки в двух элементах EditText, предназначенных для ввода и подтверждения пароля, с именами EditText_Pwdl и EditText_Pwd2. Третий элемент TextView с именем TextView_PwdProblem будет отображать информацию о том, совпадают введенные пароли или нет.

Сначала вы должны получить экземпляр каждого из элементов:

final EditText p1 = (EditText) findViewById(R.id.EditText_Pwd1); final EditText p2 = (EditText) findViewById(R.id.EditText_Pwd2); final TextView error = (TextView) findViewById(R.id.TextView PwdProblem);

После этого вы связываете экземпляр класса TextWatcher со вторым элементом EditText, используя метод addTextChangedListener (), как показано в следующем коде:

p2.addTextChangedListener(new TextWatcher() {

@Override

public void afterTextChanged(Editable s) {

String strPassl = p1.getText().toString(); String strPass2 = p2.getText().toString(); if (strPass1.equals(strPass2)) {

error.setText(R.string.settings pwd equal); } else {

error.setText(R.string.settings pwd not equal);

}

}

// Other required overrides do nothing });

Пользователь может вводить пароль элемент EditText с именем EditText_Pwd1 в обычном режиме. Однако всякий раз, когда пользователь вводит очередной символ в элемент с именем EditText_Pwd2, вы сравниваете текст в оооич длементах EditText и присваиваете соответствующий текст длеченгу TextView с именем TextView _PwdProblem, чтобы показать, совпадают введенные пароли или нет (рис. 10.4).

Рис. 10.7. Элемент Spinner в закрытом (слева) и активном (справа) состояниях

НАСТРОЙКА ЭЛЕМЕНТОВ SPINNER

Большая часть настройки элемента Spinner должна осуществляться программным путем. Как и в случае с элементом ListView, элемент Spinner использует адаптеры данных для связыва­ния содержимого из набора данных с каждым представлением, отображаемым в элементе. Чтобы загрузить данные в элемент Spinner, необходимо выполнить следующие шаги:

1.                                Получить экземпляр элемента Spinner из макета.

2.                                 Настроить адаптер данных для связывания необходимых данных с элементом.

3.                                 Вызвать метод setAdapter() элемента Spinner.

Чтобы получить экземпляр Spinner из макета, используется уже знакомый вам метод

findViewById() :

final Spinner spinner = (Spinner) findViewById(R.id.Spinner Gender);

Теперь нужно настроить ваш адаптер данных. Элемент Spinner отображает данные в закрытом и активном состояниях по-разному. Поэтому вы должны создать макеты шаблонов для обоих со­стояний. К счастью, платформа Android включает несколько специальных ресурсов макетов, кото­рые помогают создавать элементы Spinner, содержащие только текст. В частности, вы можете ис­пользовать ресурс макета с именем android.R.layout.simple_spinner_item для создания подходящего представления для каждого элемента списка в стандартном элементе Spinner. Вы можете использовать ресурс макета с именем android.R. layout. simple_spinner_dropdown_item в качестве шаблона представ­ления для раскрывающегося списка.

Используя эти удобные встроенные макеты шаблонов, вы можете загрузить ваш строковый массив с именем genders в экземпляр класса ArrayAdapter, используя метод

createFromResource() :

ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this,

R.array.genders, android.R.layout.simple spinner item); adapter.setDropDownViewResource(

android.R.layout.simple spinner dropdown item);

Наконец, вы вызываете метод setAdapter () элемента Spinner, чтобы связать загруженные данные с этим элементом:

spinner.setAdapter(adapter);

РАБОТА СО ЗНАЧЕНИЯМИ В ЭЛЕМЕНТЕ SPINNER

После того, как в элемент Spinner будут загружены данные, вы сможете узнать, какое значение выбрал пользователь, используя метод setSelection(). Например, вы знаете, что значение, соответствующее мужскому полу, хранится в строковом массиве под индексом 2 (поскольку в строковом массиве применяется индексация с нуля). Поскольку вы выбрали вариант сопостав­ления пола пользователя непосредственно с индексами в строковом массиве, вы можете выбрать в элементе Spinner значение Female (Женский), используя следующий код:

spinner.setSelection(2);

Класс элемента Spinner также предоставляет ряд методов для получения выбранного пользова­телем значения.

ПРОСЛУШИВАНИЕ СОБЫТИЙ ВЫБОРА ЗНАЧЕНИЙ В СПИСКЕ

Вам нужно сохранить выбранное значение в элементе управления Spinner сразу, как только пользователь выберет его. Для этого используется метол

setOnItemSelectedListener() элемента Spinner, чтобы установить слушателя событий выбора значений. В частности, вам нужно реализовать метод onItemSelected() класса AdapterView.setOnItemSelectedListener(), как показано в следующем коде:

spinner.setOnItemSelectedListener(

new AdapterView.OnItemSelectedListener() { @Override

public void onItemSelected(AdapterView<?> parent, View itemSelected,

int selectedltemPosition, long selectedId) {

// TODO: Save item index (selectedItemPosition) as Gender

setting

}

// … Other required overrides

});

Рис. 10.8. Экран с настройками приложения «Been There, Done That!»

КСТАТИ __________________________________________________________________

В некоторых версиях инструментария Android SDK может также потребоваться реализо­вать соответствующие «заглушки» для других методов класса

AdapterView.OnItemSelectedListener.

СОХРАНЕНИЕ ДАННЫХ ФОРМЫ С ИСПОЛЬЗОВАНИЕМ КЛАССА SHAREDPREFERENCES

Для сохранения настроек приложения вы можете использовать механизм постоянного хранения данных, реализуемый классом SharedPreferences. При помощи этого меха­низма вы можете сохранить все значения, указанные пользователем в форме на экране с настройками.

Определение записей для экземпляра класса SharedPreferences

Ранее вы добавили в базовый класс QuizActivity строку для настроек вашей игры:

public static final String GAME_PREFERENCES = "GamePrefs";

Теперь вам нужно добавить в класс QuizActivity название каждого параметра, значе­ние которого вы хотите сохранить в настройках:

public static final String GAME_PREFERENCES_NICKNAME = "Nickname"; // Тип String

public static final String GAME_PREFERENCES_EMAIL = "Email"; //Тип String

public static final String GAME_PREFERENCES_PASSWORD = "Password";

//Тип String

public static final String GAME_PREFERENCES_DOB = "DOB"; //Тип Long

public static final String GAME_PREFERENCES_GENDER = "Gender"; //Тип Int

Сохранение настроек параметров с использованием экземпляра

класса SharedPreferences

Теперь, когда вы определили названия параметров, вы можете сохранить в настройках игры любые значения этих параметров, вводимые пользователем. Внутри класса QuizSettingsActivity сначала нужно объявить переменную-член, представляющую экземпляр класса

SharedPreferences:

SharedPreferences mGameSettings;

Внутри метода onCreate () деятельности вы инициализируете эту переменную-член следующим образом:

mGameSettings =

getSharedPreferences(GAME_PREFERENCES, Context. MODE_PRIVATE);

Вы передаете и указанный метод название вашего экземпляра класса SharedPreferences (строковая константа с именем GAME_PREFERENCES, которую вы создали в классе QuizActivity). Режим MODE_PRIVATE представляет стандартное разрешение, используемое для закрытых файлов приложения.

Теперь, в любом месте кода, где нужно сохранить какую-либо настройку игры, вы просто полу­чаете экземпляр класса SharedPreferences.Editor, присваиваете нужному параметру желаемое значение и сохраняете произведенное изменение. Например, чтобы сохранить информа­цию из элемента EditText параметра Nickname (Ник), сначала вы получаете введенный поль­зователем текст, используя метод getText () элемента EditText:

final EditText nicknameText =

(EditText) findViewById(R.id.EditText_Nickname); String strNickname = nicknameText.getText().toString();

После того, как вы получите значение типа String из поля ввода, представленного элементом EditText, вы можете сохранить это значение в экземпляре класса

SharedPreferences . Editor, используя метод putString () :

Editor editor = mGameSettings.edit();

editor.putString(GAME_PREFERENCES_NICKNAME, strNickname); editor.commit();

Настройки параметров Nickname (Ник), Email и Password (Пароль) могут быть сохранены в виде значений типа string, а настройки параметров Date of Birth (Дата рождения) и Gender (Пол) — в виде значений типа long и integer соответственно. Чтобы сохранить значения этих параметров, вы должны получить введенное пользователем значение из соответствующего элемента, при необходимости преобразовать это значение, и затем сохранить его с использованием методов putLong() и putInt() класса Shared Preferences.Editor.

Пока вы можете сохранить введенные пользователем значения в поля ввода Nickname (Ник), Email и Gender (Пол). С параметрами Date of Birth (Дата рождения) и Password (Пароль) вы будете работать в следующем часе, когда будете реализовывать диалоговые окна DatePickerDialog (для ввода даты) и Dialog (для ввода пароля). Если вы вернетесь к исходному коду класса QuizSettingsActivity и найдете строки кода, отмеченные комментариями TODO, вы увидите, где должно происходить сохранение значений параметров.

Чтение значений параметров из экземпляра класса SharedPreferences

Приступив к сохранению значений параметров с использованием механизмов постоянного хране­ния данных, вам понадобится способ для чтения сохраненных значений и загрузим их в поля ввода формы (для последующего редактирования). Для этого вам нужно получить доступ к настройкам игры и проверить. существует ли среди этих настроек нужный вам параметр. Например, вы можете захотеть проверить, было ли указано значение для параметра Nickname (Ник), и, если значение было указано, загрузить это значение в элемент EditText с именем EditTextNickname. Для этого вы можете воспользоваться методами contains() и getString() класса SharedPreferences:

final EditText nicknameText =

(EditText) findViewById(R.id.EditText_Nickname); if (mGameSettings.contains(GAME_PREFERENCES_NICKNAME)) { nicknameText.setText(mGameSettings.getString( GAME_PREFERENCES_NICKNAME, ""));

}

В этом коде вы проверяете существование параметра с именем, определяемым константой

game________ preferences     nickname, в экземпляре класса SharedPreferences, используя метод con-

tains(). Если метод contains() возвращает значение true, вы извлекаете значение данного параметра (значение типа String) из экземпляра класса SharedPreferences, ис­пользуя метод getString () .

Параметры Nickname (Ник), Email и Password (Пароль) представляются строковыми значе­ниями и могут извлекаться при помощи метода getString(). Вместе с тем значение параметра Date of Birth (Дата рождения) должно извлекаться при помощи метода getLong(), а для полу­чения значения параметра Gender (Пол) требуется использование метода getInt().

ЗНАЕТЕ ЛИ ВЫ, ЧТО… _____________________________________________________

Настройки приложения хранятся в файловой системе Android в виде XML-файлов. К фай­лам настроек можно обращаться с использованием панели File Explorer (Проводник) пер­спективы DDMS среды разработки Eclipse. Файлы, создаваемые экземплярами класса SharedPreferences, находятся в следующем каталоге:

/data/data/<имя пакета>/shared_prefs/<имя файла настроек>.xml.

Наконец для отладочных целей вы переопределяете метод onDestroy() класса QuizSettingsActivity таким образом, чтобы при уничтожении экрана с настрой­ками происходило журналирование всех текущих значений параметров: @Override

protected void onDestroy() {

Log. d (DEBUG_TAG, "SHARED PREFERENCES"); Log. d(DEBUG_TAG, "Nickname is: "

+ mGameSettings.getString(GAME_PREFERENCES_NICKNAME, "Not set")); Log. d(DEBUG_TAG, "Email is: "

+ mGameSettings.getString(GAME_PREFERENCES_EMAIL, "Not set")); Log. d(DEBUG_TAG, "Gender (M=1, F=2r U=0) is: " + mGameSettings.getInt(GAME_PREFERENCES_GENDER, 0)); // We are not saving the password yet Log. d(DEBUG_TAG, "Password is: "

+ mGameSettings.getString(GAME_PREFERENCES_PASSWORD, "Not set")); // We are not saving the date of birth yet Log. d(DEBUG_TAG, "DOB is: "

+ DateFormat.format("MMMM dd, yyyy", mGameSettings.getLong( GAME_PREFERENCES_DOB, 0))); super.onDestroy();

}

Теперь всякий раз, когда будет происходить уничтожение экземпляра класса QuizSettingsActivity (например, когда пользователь нажимает кнопку Back на теле­фоне), сохраненные настройки параметров будут отображаться на панели LogCat.

ИТОГИ

В этом часе вы добавили форму на экран с настройками приложения-викторины «Been There, Done That!». Форма содержит разнообразные параметры, включая поля ввода различных типов, реализуемых с использованием элементов EditText, и раскрывающийся список, реализуемый при помощи элемента Spinner. Также вы сохранили свободное пространство на экране, вос­пользовавшись двумя элементами Button, которые в будущем будут использованы для отобра­жения диалоговых окон Dialog. Наконец, вы реализовали простейший механизм загрузки и сохра­нения настроек игры при помощи класса SharedPreferences.

ВОПРОСЫ И ОТВЕТЫ

Вопрос: Почему бы не воспользоваться обычными кнопками Save (Сохранить) и Cancel (Отме­нить), которые используются на веб-формах?

Ответ: Формы для ввода данных в приложениях, функционирующих на мобильных устройствах, действительно могут быть разработаны с применением этого традиционного подхода, но во внима­ние должны приниматься накладные расходы, связанные с механизмом управления состояниями. (События жизненного цикла деятельности, например пауза и восстановление, могут требовать не­медленного сохранения и восстановления введенных данных.). Распространенный подход при раз­работке форм для ввода данных для мобильных устройств основан на сохранении значений полей формы по мере ввода данных пользователем.

Вопрос: Элемент Spinner должен заполняться данными исключительно из массива?

Ответ: Нет, данные, используемые элементом Spinner, могут загружаться из различных источ­ников при помощи адаптера данных. Например, содержимое элемента Spinner может загру­жаться из базы данных.

ПРАКТИКУМ Контрольные вопросы

1.                                Верно ли это? Элементы EditText наследуются от элементов TextView.

2.                                 Какие типы кнопок доступны в платформе Android?

A.                               Button.

B.                                TextButton.

C.                                ImageButton.

3.                                  Верно ли это? Данные типа Calendar можно непосредственно сохранить в экземпляре класса SharedPreferences.

Ответы

1.                                 Верно. Класс TextView вместе с его известными атрибутами и методами, например, методами getText() и setText(), — это базовый класс для класса

EditText.

2.                                 А и В. В платформе Android существует два типа кнопок: элемент Button представляет простую кнопку с надписью. Элемент ImageButton представляет кнопку с графическим и изображением типа Drawabe.

3.                                 Неверно. Классом SharedPreferences поддерживаются следующие типы данных: Boolean, float, int, long и String. Для сохранения даты или времени можно рассмотреть вариант использования значений типа long (выраженных в миллисекундах с начала Эпохи).

Литература: Дэрси JI., Android за 24 часа. Программирование приложений под операционную систему Google/ ДэрсиЛ., КондерШ. — М.: Рид Групп, 2011. — 464 с. — (Профессиональные компьютерные книги). ISBN 978-5-4252-0318-2

По теме:

  • Комментарии