В этом уроке мы:

- создадим контекстное меню

Контекстное меню вызывается в Андроид длительным нажатием на каком-либо экранном компоненте. Обычно оно используется в списках, когда на экран выводится список однородных объектов (например письма в почт.ящике) и, чтобы выполнить действие с одним из этих объектов, мы вызываем контекстное меню для него. Но т.к. списки мы еще не проходили, сделаем пример попроще и будем вызывать контекстное меню для TextView.

 

Создадим проект:

Project name: P0151_ContextMenu
Build Target: Android 2.3.3
Application name: ContextMenu
Package name: ru.startandroid.develop.contextmenu
Create Activity: MainActivity

 

Откроем main.xml и нарисуем там два TextView:

<?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:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_width="wrap_content"
        android:id="@+id/tvColor"
        android:layout_marginBottom="50dp"
        android:layout_marginTop="50dp"
        android:text="Text color">
    </TextView>
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="22sp"
        android:id="@+id/tvSize"
        android:text="Text size">
    </TextView>
</LinearLayout>

 

Для первого TextView мы сделаем контекстное меню, с помощью которого будем менять цвет текста. Для второго – будем менять размер текста.

Принцип создания контекстного меню похож на создание обычного меню. Но есть и отличия.

Метод создания onCreateContextMenu вызывается каждый раз перед показом меню. На вход ему передается:

- ContextMenu, в который мы будем добавлять пункты
- View - элемент экрана, для которого вызвано контекстное меню
- ContextMenu.ContextMenuInfo – содержит доп.информацию, когда контекстное меню вызвано для элемента списка. Пока мы это не используем, но, когда будем изучать списки, увидим, что штука полезная.

 

Метод обработки onContextItemSelected аналогичный методу onOptionsItemSelected для обычного меню. На вход передается MenuItem – пункт меню, который был нажат.

 

Также нам понадобится третий метод registerForContextMenu. На вход ему передается View и это означает, что для этой View необходимо создавать контекстное меню. Если не выполнить этот метод, контекстное меню для View создаваться не будет.

 

Давайте кодить, открываем MainActivity.java. Опишем и найдем TextView и укажем, что необходимо создавать для них контекстное меню.

  TextView tvColor, tvSize;
  
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tvColor = (TextView) findViewById(R.id.tvColor);
        tvSize = (TextView) findViewById(R.id.tvSize);
        
        // для tvColor и tvSize необходимо создавать контекстное меню
        registerForContextMenu(tvColor);
        registerForContextMenu(tvSize);
            
    }

 

Теперь опишем создание контекстных меню. Используем константы для хранения ID пунктов меню.

  final int MENU_COLOR_RED = 1;
  final int MENU_COLOR_GREEN = 2;
  final int MENU_COLOR_BLUE = 3;
  
  final int MENU_SIZE_22 = 4;
  final int MENU_SIZE_26 = 5;
  final int MENU_SIZE_30 = 6;

  

И создаем

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
      // TODO Auto-generated method stub
      switch (v.getId()) {
    case R.id.tvColor:
      menu.add(0, MENU_COLOR_RED, 0, "Red");
      menu.add(0, MENU_COLOR_GREEN, 0, "Green");
      menu.add(0, MENU_COLOR_BLUE, 0, "Blue");
      break;
    case R.id.tvSize:
      menu.add(0, MENU_SIZE_22, 0, "22");
      menu.add(0, MENU_SIZE_26, 0, "26");
      menu.add(0, MENU_SIZE_30, 0, "30");
      break;
    }
    }

 

Обратите внимание, что мы по ID определяем View, для которого вызвано контекстное меню и в зависимости от этого создаем определенное меню. Т.е. если контекстное меню вызвано для tvColor, то мы создаем меню с перечислением цветов, а если для tvSize с размерами шрифта.

В качестве ID пунктов мы использовали константы. Группировку и сортировку не используем, поэтому используем нули в качестве соответствующих параметров.

Можно все сохранить и запустить. При долгом нажатии на TextView должны появляться контекстные меню.

 

Но нажатие на них ничего не дает, т.к. мы не прописали обработку в методе onContextItemSelected. Давайте пропишем:

    @Override
    public boolean onContextItemSelected(MenuItem item) {
      // TODO Auto-generated method stub
      switch (item.getItemId()) {
      // пункты меню для tvColor
    case MENU_COLOR_RED:
      tvColor.setTextColor(Color.RED);
      tvColor.setText("Text color = red");
      break;
    case MENU_COLOR_GREEN:
      tvColor.setTextColor(Color.GREEN);
      tvColor.setText("Text color = green");
      break;
    case MENU_COLOR_BLUE:
      tvColor.setTextColor(Color.BLUE);
      tvColor.setText("Text color = blue");
      break;
    // пункты меню для tvSize
    case MENU_SIZE_22:
      tvSize.setTextSize(22);
      tvSize.setText("Text size = 22");
      break;
    case MENU_SIZE_26:
      tvSize.setTextSize(26);
      tvSize.setText("Text size = 26");
      break;
    case MENU_SIZE_30:
      tvSize.setTextSize(30);
      tvSize.setText("Text size = 30");
      break;
      }
      return super.onContextItemSelected(item);
    }

 

В этом методе мы определяем по ID, какой пункт меню был нажат. И выполняем соответствующие действия: меняем цвет текста для tvColor или размер шрифта для tvSize. Сохраняем, запускаем и проверяем, что контекстные меню теперь реагируют на нажатия и делают то, что от них требуется.

 

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

Мы использовали метод registerForContextMenu (View view) для включения контекстного меню для определенного View. Этот метод принадлежит классу Activity. Я посмотрел исходники этого метода, там написано следующее:

  public void registerForContextMenu(View view) {
    view.setOnCreateContextMenuListener(this);
  }

 

Вспоминаем наш урок по обработчикам и смотрим хелп по методу setOnCreateContextMenuListener (View.OnCreateContextMenuListener l). Получается, что View в качестве обработчика создания контекстного меню использует объект this. В данном случае, этот код в Activity, значит this – это Activity и есть. Т.е. когда View хочет показать контекстное меню, оно обращается к обработчику (Activity), а он уже выполняет свой метод onCreateContextMenu. Т.е. тот же самый принцип, что и при обычном нажатии (Click).

 

И строка в MainActivity.java:

registerForContextMenu(tvColor);

 

абсолютно равнозначна этой строке:

tvColor.setOnCreateContextMenuListener(this);

 

Вообще мы можем создать свой объект, реализующий интерфейс View.OnCreateContextMenuListener и использовать его вместо Activity в качестве обработчика создания контекстного меню.

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

 

Полный код урока:

public class MainActivity extends Activity {

  final int MENU_COLOR_RED = 1;
  final int MENU_COLOR_GREEN = 2;
  final int MENU_COLOR_BLUE = 3;

  final int MENU_SIZE_22 = 4;
  final int MENU_SIZE_26 = 5;
  final int MENU_SIZE_30 = 6;

  TextView tvColor, tvSize;

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

    tvColor = (TextView) findViewById(R.id.tvColor);
    tvSize = (TextView) findViewById(R.id.tvSize);

    // для tvColor и tvSize необходимо создавать контекстное меню
    registerForContextMenu(tvColor);
    registerForContextMenu(tvSize);
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenuInfo menuInfo) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.tvColor:
      menu.add(0, MENU_COLOR_RED, 0, "Red");
      menu.add(0, MENU_COLOR_GREEN, 0, "Green");
      menu.add(0, MENU_COLOR_BLUE, 0, "Blue");
      break;
    case R.id.tvSize:
      menu.add(0, MENU_SIZE_22, 0, "22");
      menu.add(0, MENU_SIZE_26, 0, "26");
      menu.add(0, MENU_SIZE_30, 0, "30");
      break;
    }
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch (item.getItemId()) {
    // пункты меню для tvColor
    case MENU_COLOR_RED:
      tvColor.setTextColor(Color.RED);
      tvColor.setText("Text color = red");
      break;
    case MENU_COLOR_GREEN:
      tvColor.setTextColor(Color.GREEN);
      tvColor.setText("Text color = green");
      break;
    case MENU_COLOR_BLUE:
      tvColor.setTextColor(Color.BLUE);
      tvColor.setText("Text color = blue");
      break;
    // пункты меню для tvSize
    case MENU_SIZE_22:
      tvSize.setTextSize(22);
      tvSize.setText("Text size = 22");
      break;
    case MENU_SIZE_26:
      tvSize.setTextSize(26);
      tvSize.setText("Text size = 26");
      break;
    case MENU_SIZE_30:
      tvSize.setTextSize(30);
      tvSize.setText("Text size = 30");
      break;
    }
    return super.onContextItemSelected(item);
  }
}

 

На следующем уроке:

- рисуем экран программно, а не через layout-файл


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

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



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal