Главная » Разработка для Android » Совершенствование приложения To-Do List

0

В следующем примере1  вы добавите поддержку  простого меню в при- ложение To-Do List, которое создали в главе 2 (и улучшили в предыдущих разделах текущей главы).

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

1. Начните  с класса Активности ToDoList. Импортируйте пакеты, кото- рые вам понадобятся для поддержки  функциональности, связанной с меню.

import android.view.Menu; import android.view.MenuItem; import android.view.ContextMenu; import android.widget.AdapterView;

2. Добавьте приватные  статические  финальные свойства,  содержащие уникальные идентификаторы для каждого пункта меню.

static final private int ADD_NEW_TODO = Menu.FIRST;

static final private int REMOVE_TODO = Menu.FIRST + 1;

3. Переопределите метод onCreateOptionsMenu, создав два новых пункта меню для добавления  и удаления элементов в списке задач. Укажите соответствующий текст, назначьте ресурсы со значками  и сокращен- ные клавиатурные команды для каждого пункта.

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

// Создайте новые пункты меню.

1     Все фрагменты  кода в этом примере — часть проекта Todo List 2 из главы 4, их можно за- грузить на сайте Wrox.com.

MenuItem itemAdd = menu.add(0, ADD_NEW_TODO, Menu.NONE, R.string.add_new);

MenuItem itemRem = menu.add(0, REMOVE_TODO, Menu.NONE, R.string.remove);

// Установите значки itemAdd.setIcon(R.drawable.add_new_item); itemRem.setIcon(R.drawable.remove_item);

// Назначьте сокращенные клавиатурные команды для каждого пункта. itemAdd.setShortcut(‘0′, ‘a’);

itemRem.setShortcut(‘1′, ‘r’);

return true;

}

Если запустить Активность и нажать аппаратную кнопку ????, на экра- не должно отобразиться меню, как показано на рис. 4.10.

Рис. 4.10.

4. После  заполнения меню для Активности нужно  создать  еще одно меню — контекстное. Сперва измените метод onCreate, зарегистриро- вав элемент ListView, который  будет использоваться в контекстном меню. Затем  переопределите обработчик  onCreateContextMenu,  до- бавив в объект ContextMenu пункт ???????.

@Override

public void onCreate(Bundle savedInstanceState) {

[ … ранее написанный код для метода onCreate … ]

registerForContextMenu(myListView);

}

@Override

public void onCreateContextMenu(ContextMenu menu, View v,

ContextMenu.ContextMenuInfo menuInfo) {

super.onCreateContextMenu(menu, v, menuInfo);

menu.setHeaderTitle("Selected To Do Item");

menu.add(0, REMOVE_TODO, Menu.NONE, R.string.remove);

}

5. Теперь нужно сделать так, чтобы внешний вид меню изменялся в за- висимости от программного контекста. Для этого переопределите ме- тод onPrepareOptionsMenu. Объект MenuItem должен быть изменен, чтобы во время добавления  новой задачи показывать  надпись Cancel вместо Delete.

private boolean addingNew = false;

@Override

public boolean onPrepareOptionsMenu(Menu menu) {

super.onPrepareOptionsMenu(menu);

int idx = myListView.getSelectedItemPosition(); String removeTitle = getString(addingNew ?

R.string.cancel : R.string.remove);

MenuItem removeItem = menu.findItem(REMOVE_TODO); removeItem.setTitle(removeTitle); removeItem.setVisible(addingNew || idx > -1);

return true;

}

6. Чтобы код из предыдущего  пункта работал, необходимо, чтобы эле- менты todoListItems и ListView  были видны за пределами  метода onCreate. То же самое сделайте  и для ArrayAdapter и EditText для добавления поддержки действий ???????? и ???????, которые будут реа- лизованы  позже.

private ArrayList<String> todoItems;

private ListView myListView; private EditText myEditText; private ArrayAdapter<String> aa;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// Получите ссылки на элементы пользовательского интерфейса

myListView = (ListView)findViewById(R.id.myListView);

myEditText = (EditText)findViewById(R.id.myEditText);

todoItems = new ArrayList<String>();

int resID = R.layout.todolist_item;

aa = new ArrayAdapter<String>(this, resID, todoItems);

myListView.setAdapter(aa);

myEditText.setOnKeyListener(new OnKeyListener() {

public boolean onKey(View v, int keyCode, KeyEvent event) {

if (event.getAction() == KeyEvent.ACTION_DOWN)

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)

{

todoItems.add(0, myEditText.getText().toString());

myEditText.setText(""); aa.notifyDataSetChanged(); return true;

}

}

});

return false;

registerForContextMenu(myListView);

}

7. Необходимо контролировать выбор пунктов в меню. Переопределите методы onOptionsItemSelected и onContextItemSelected, чтобы вы- зывать заглушки, которые обрабатывают новые объекты MenuItem.

7.1.Начните  с переопределения обработчика  onOptionsItemSelected, чтобы реагировать на выделение пунктов в главном меню. Для пунк- та, который  отвечает за удаление,  можете использовать метод getSelectedItemPosition из объекта ListView, чтобы находить вы- бранный элемент.

@Override

public boolean onOptionsItemSelected(MenuItem item) {

super.onOptionsItemSelected(item);

int index = myListView.getSelectedItemPosition();

switch (item.getItemId()) {

case (REMOVE_TODO): {

if (addingNew) {

cancelAdd();

}

else {

removeItem(index);

}

return true;

}

case (ADD_NEW_TODO): {

addNewItem();

return true;

}

}

return false;

}

7.2.Переопределите метод onContextItemSelected, чтобы обрабатывать выбор пунктов в контекстном меню. Имейте в виду, что применя- емая реализация интерфейса ContextMenuInfo привязана к классу AdapterView. Она содержит ссылки на Представление, которое вы- звало контекстное  меню, и индекс для данных, принадлежащих исходному Адаптеру (Adapter). Используйте последний в качестве индекса элемента, который нужно удалить.

@Override

public boolean onContextItemSelected(MenuItem item) {

super.onContextItemSelected(item);

switch (item.getItemId()) {

case (REMOVE_TODO): {

AdapterView.AdapterContextMenuInfo menuInfo;

menuInfo =(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();

int index = menuInfo.position;

removeItem(index);

return true;

}

}

return false;

}

7.3.Создайте  заглушки,  которые вызываются в обработчике  onCon- textItemSelected, созданном выше.

private void cancelAdd() {

}

private void addNewItem() {

}

private void removeItem(int _index) {

}

8. Реализуйте каждую заглушку, чтобы предоставить  новую функцио- нальность.

private void cancelAdd() {

addingNew = false;

myEditText.setVisibility(View.GONE);

}

private void addNewItem() {

addingNew = true;

myEditText.setVisibility(View.VISIBLE);

myEditText.requestFocus();

}

private void removeItem(int _index) { todoItems.remove(_index); aa.notifyDataSetChanged();

}

9. После  того как новая  задача добавлена,  необходимо  скрыть строку ввода. Измените обработчик onKeyListener в методе onCreate, чтобы он вызывал функцию  cancelAdd после добавления  нового элемента.

myEditText.setOnKeyListener(new OnKeyListener() {

public boolean onKey(View v, int keyCode, KeyEvent event) {

if (event.getAction() == KeyEvent.ACTION_DOWN)

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)

{

todoItems.add(0, myEditText.getText().toString());

myEditText.setText(""); aa.notifyDataSetChanged(); cancelAdd();

return true;

}

}

});

return false;

10. В завершение сделайте пользовательский интерфейс логичным и по- следовательным, изменив разметку в файле main.xml таким образом, чтобы строка ввода была скрыта, пока пользователь не решит добавить новый элемент:

<EditText android:id="@+id/myEditText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:visibility="gone"

/>

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

Резюме

Теперь  вы знакомы  с основными  подходами  к созданию  интуитивно понятных  пользовательских интерфейсов для приложений в Android. Вы изучили  Представления и разметку,  познакомились с системой  для управ- ления меню.

Научились создавать  экраны  с Активностями, позиционируя Представ- ления с помощью менеджеров  компоновки (можно  создавать  как в коде программы, так и в виде ресурсов).  Вы узнали, как расширять,  группиро- вать и создавать новые элементы, основанные на классе View, чтобы иметь возможность обеспечивать  нестандартный внешний  вид и поведение  для своих приложений.

В этой главе вы также:

познакомились с некоторыми элементами управления и виджетами, которые являются частью Android SDK;

узнали, как использовать свои нестандартные Представления внутри

Активностей;

изучили создание динамических ресурсов Drawable в формате XML;

научились  создавать  пользовательские интерфейсы, которые не за- висят от разрешения и плотности пикселов на экране;

узнали, как создавать и использовать главные и контекстные меню;

расширили возможности приложения To-Do List, добавив в него под- держку нестандартных Представлений и функции меню;

создали с нуля новый элемент CompassView.

После рассмотрения основ проектирования пользовательского интер- фейса в Android  можно перейти  к следующей  главе, которая  посвящена связыванию компонентов  приложения с помощью Намерений, Широкове- щательных приемников  и Адаптеров. Вы узнаете, как запускать  новые Актив- ности, передавать и принимать запросы на выполнение действий, научитесь взаимодействовать с Интернетом, а также рассмотрите класс Dialog.

Источник: Майер P. Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с. — (Мировой компьютерный бестселлер).

По теме:

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