Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Программное создание контекстного меню
Контекстное меню через ресурсы
Кроме стандартного меню в Android используется также контекстное меню, вызываемое при нажатии на объект в течение двух-трёх секунд (событие long-press). Также на некоторых моделях устройств контекстное меню можно вызвать при нажатии трекбола или средней кнопки манипулятора D-pad. В отличие от обычного меню, в контекстном меню не поддерживаются значки и быстрые клавиши. Второе важно отличие - контекстное меню применимо к компоненту, а меню к активности. Поэтому в приложении может быть одно меню и несколько контекстных меню, например, у каждого элемента TextView.
Для создания контекстного меню используется метод обратного вызова onCreateContextMenu(). В данный метод можно добавлять пункты меню при помощи методов add(). C помощью метода onContextItemSelected() можно обрабатывать выбор пункта. Но сначала надо зарегистрировать контекстное меню для нужного объекта, например, для TextView при помощи метода registerForContextMenu().
// Kotlin
package ru.alexanderklimov.contextmenu
import android.os.Bundle
import android.view.ContextMenu
import android.view.Menu
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
companion object {
const val IDM_OPEN = 101
const val IDM_SAVE = 102
}
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.textview)
registerForContextMenu(textView)
}
override fun onCreateContextMenu(
menu: ContextMenu?,
v: View?,
menuInfo: ContextMenu.ContextMenuInfo?
) {
super.onCreateContextMenu(menu, v, menuInfo)
menu?.add(Menu.NONE, IDM_OPEN, Menu.NONE, "Открыть")
menu?.add(Menu.NONE, IDM_SAVE, Menu.NONE, "Сохранить")
}
}
// Java
package ru.alexanderklimov.contextmenu;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
public static final int IDM_OPEN = 101;
public static final int IDM_SAVE = 102;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
TextView textView2 = findViewById(R.id.textView2);
registerForContextMenu(textView);
registerForContextMenu(textView2);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(Menu.NONE, IDM_OPEN, Menu.NONE, "Открыть");
menu.add(Menu.NONE, IDM_SAVE, Menu.NONE, "Сохранить");
}
}
Если запустить проект, то уже сейчас можно увидеть контекстное меню, которое пока не будет реагировать на выбранные пункты меню.
Допишем код для выбранного пункта меню.
// Kotlin
override fun onContextItemSelected(item: MenuItem): Boolean {
val message: CharSequence = when (item.itemId) {
IDM_OPEN -> "Выбран пункт Открыть"
IDM_SAVE -> "Выбран пункт Сохранить"
else -> return super.onContextItemSelected(item)
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
return true
}
// Java
@Override
public boolean onContextItemSelected(MenuItem item)
{
CharSequence message;
switch (item.getItemId())
{
case IDM_OPEN:
message = "Выбран пункт Открыть";
break;
case IDM_SAVE:
message = "Выбран пункт Сохранить";
break;
default:
return super.onContextItemSelected(item);
}
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return true;
}
Если вам нужно создать локализованный продукт, то программное добавление пунктов контекстного меню не подойдёт. В таких случаях используется традиционный способ через файл ресурсов, рекомендованный Google.
Создадим XML-файл res/menu/context_menu.xml для меню, а также добавим в разметку ещё один TextView:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/change_color"
android:title="@string/titleChangeColor" />
<item android:id="@+id/change_textsize"
android:title="@string/titleChangeTextSize" />
</menu>
// добавить в strings.xml
<string name="titleChangeColor">Поменять цвет</string>
<string name="titleChangeTextSize">Поменять размер шрифта</string>
Добавляем код к существующему.
// Kotlin
override fun onCreateContextMenu(
menu: ContextMenu?,
v: View?,
menuInfo: ContextMenu.ContextMenuInfo?
) {
super.onCreateContextMenu(menu, v, menuInfo)
menuInflater.inflate(R.menu.context_menu, menu)
}
override fun onContextItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.change_color -> {
textView.setBackgroundColor(Color.RED)
Toast.makeText(this, "Меняем цвет", Toast.LENGTH_SHORT).show()
}
R.id.change_textsize -> Toast.makeText(this, "Меняем шрифта", Toast.LENGTH_SHORT)
.show()
else -> return super.onContextItemSelected(item)
}
return true
}
// Java
private TextView textView3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
textView3 = findViewById(R.id.textView3);
registerForContextMenu(textView3);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item)
{
CharSequence message;
switch (item.getItemId())
{
case R.id.change_color:
message = "Меняем цвет";
textView3.setBackgroundColor(Color.RED);
break;
case R.id.change_textsize:
message = "Меняем размер шрифта";
textView3.setTextSize(18);
break;
default:
return super.onContextItemSelected(item);
}
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return true;
}
Мы используем похожий код, как и при создании стандартного меню. В результате получим контекстное меню, созданное из ресурсов. При выборе нужного пункта изменится либо цвет, либо размер шрифта в TextView.
Создание контекстного меню внутри фрагмента