Руководство Android ContextMenu
View more Tutorials:
Если вы не можете выделить какое-либо пространство пользовательского интерфейса для нужной функции, вы можете использовать Context Menu (Контекстное меню), Context Menu это плавающее меню (floating menu) отображающее для ответа на долгое нажатие (long press), по умолчанию 500 милисекунд. Context Menu может содержать много Menu Item и Sub Menu.

Стандартное долгое нажатие (long press) в Android это 500 милисекунды, вы можете получить данное значение вызывая метод ViewConfiguration.getLongPressTimeout(). Пользователь может поменять данное значение в Settings, он будет работать со всеми приложениями на устройствами.

Как разработчик, вы не можете настроить другое значение для "период времение долгого нажатия", но вы можете использовать некоторые приемы для симулирования долгого нажатия (long press) с кастомизированным временем и выполнения связанных действий. (Смотрите далее в приложении в конце статьи).
Когда View регистрируется с событием Long-Press, система вызовет метод onCreateContextMenu(), чтобы создать и отобразить Context Menu.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.button = (Button) this.findViewById(R.id.button_test); this.registerForContextMenu(this.button); } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); menu.setHeaderTitle("Context Menu"); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.layout_context_menu, menu); } // You may not need "Android Resource File" to have a ContextMenu. // Using Java to create Context Menu. public void onCreateContextMenu_2(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); menu.setHeaderTitle("Context Menu"); // groupId, itemId, order, title MenuItem menuItemUpload = menu.add(1, 1, 1, "Upload"); MenuItem menuItemBookmark = menu.add(2, 2, 2, "Bookmark"); // groupId, itemId, order, title SubMenu subMenuShare= menu.addSubMenu(3, 3, 3, "Share"); subMenuShare.add(4, 31, 1, "Google" ); subMenuShare.add(5, 32, 2, "Instagram"); }
Когда пользователь нажимает на Menu Item, вызывается метод onContextItemSelected().
@Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menuItem_bookmark: Toast.makeText(this, "Bookmark", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_upload: Toast.makeText(this, "Upload", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_facebook: Toast.makeText(this, "Share Facebook", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_instagram: Toast.makeText(this, "Share Instagram", Toast.LENGTH_SHORT).show(); break; default: Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show(); break; } return true; }
Вы можете использовать XML Android Resource File для дизайна интерфейса Context Menu. Но Context Menu приложения обычно довольно прост, поэтому создание Context Menu полностью из Java кода тоже является хорошим выбором (Больше примеров ниже).

Примечание: Некоторые атрибуты (attribute) у <item> (Menu Item) не работают, когда они расположены в Context Menu, например:
- app:showAsAction
- android:icon (Not work in Android 3.0+/API 11+)
OK, теперь мы выполним пример Context Menu, просмотрим пример:

На Android Studio создайте project.

- Name: ContextMenuExample
- Package name: org.o7planning.contextmenuexample

Примечание: Начиная с Android 3.0 (API 11), ContextMenu не поддерживает Icon, но вы можете скопировать Icon ниже в папку drawable для поддержки старых устройств Android или пропустите этот шаг.
icon_upload.png | icon_bookmark.png | icon_share.png |

Главный интерфейс приложения очень прост, имеется только один Button, когда пользователь делает долгое нажатие (Long press) на Button, отобразится Context Menu.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:text="Long Press Me" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
На Android Studio выберите:
- File > New > Android Resource File

- File name: layout_context_menu.xml
- Resource type: Menu


На Android Studio смоделируйте интерфейс Context Menu:

Настройте ID, Title, Icon для Menu Item:

layout_context_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menuItem_upload" android:icon="@drawable/icon_upload" android:title="Upload" /> <item android:id="@+id/menuItem_bookmark" android:icon="@drawable/icon_bookmark" android:title="Bookmark" /> <item android:id="@+id/menuItem_share" android:icon="@drawable/icon_share" android:title="Share"> <menu> <item android:id="@+id/menuItem_facebook" android:title="Facebook" /> <item android:id="@+id/menuItem_instagram" android:title="Instagram" /> </menu> </item> </menu>
MainActivity.java
package org.o7planning.contextmenuexample; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final String LOG_TAG = "ContextMenuExample"; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.button = (Button) this.findViewById(R.id.button_test); this.registerForContextMenu(this.button); } @SuppressLint("RestrictedApi") @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); menu.setHeaderTitle("Context Menu"); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.layout_context_menu, menu); // com.android.internal.view.menu.ContextMenuBuilder Log.i(LOG_TAG, ">>>>> Menu class: " + menu.getClass().getName()); // com.android.internal.view.menu.MenuBuilder Log.i(LOG_TAG, ">>>>> Menu superclass: " + menu.getClass().getSuperclass().getName()); } // You may not need "Android Resource File" to have a ContextMenu. // Using Java to create Context Menu. @SuppressLint("RestrictedApi") public void onCreateContextMenu_2(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); menu.setHeaderTitle("Context Menu"); // groupId, itemId, order, title MenuItem menuItemUpload = menu.add(1, 1, 1, "Upload"); MenuItem menuItemBookmark = menu.add(2, 2, 2, "Bookmark"); menuItemUpload.setIcon(R.drawable.icon_upload); menuItemBookmark.setIcon(R.drawable.icon_bookmark); // groupId, itemId, order, title SubMenu subMenuShare= menu.addSubMenu(3, 3, 3, "Share"); subMenuShare.setIcon(R.drawable.icon_share); subMenuShare.add(4, 31, 1, "Google" ); subMenuShare.add(5, 32, 2, "Instagram"); } @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menuItem_bookmark: Toast.makeText(this, "Bookmark", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_upload: Toast.makeText(this, "Upload", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_facebook: Toast.makeText(this, "Share Facebook", Toast.LENGTH_SHORT).show(); break; case R.id.menuItem_instagram: Toast.makeText(this, "Share Instagram", Toast.LENGTH_SHORT).show(); break; default: Toast.makeText(this, item.getTitle(), Toast.LENGTH_SHORT).show(); break; } return true; } }
-
TODO