先来认识一下上下文菜单是什么样子的?如图,当长按一个控件时弹出来的菜单叫做上下文菜单:
图中第一个和第二个就是一个上下文菜单,第二个菜单里面还有一层菜单,这个上下文菜单被绑定到注册按钮中,也就是长按注册按钮后就会弹出上下文菜单,当然这个上下文菜单也可以绑定到其他的控件中,看自己的意愿了。
下面我们就来看看如何实现这么样的一个功能吧!
首先就是新建一个context.xml文件:
然后就是编写context.xml文件了:里面就是放了两个菜单,在第二个菜单里面又放了两个菜单。
剩下的就是怎么把菜单和按钮绑定和每个菜单的点击事件了:
1.注册
registerForContextMenu(findViewById(R.id.button)); 通过这句话来注册,也就是把这个菜单和id为button的按钮绑定,长按id为button的按钮后弹出菜单。
2.创建
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {super.onCreateContextMenu(menu, v, menuInfo);getMenuInflater().inflate(R.menu.context,menu);
}
3.菜单项的操作
@SuppressLint("NonConstantResourceId")
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {int id = item.getItemId();if (id == R.id.diyi){Toast.makeText(this, "第一个按钮被按下", Toast.LENGTH_SHORT).show();}if (id == R.id.dier){Toast.makeText(this, "第2个按钮被按下", Toast.LENGTH_SHORT).show();}if (id == R.id.disan){Toast.makeText(this, "第3个按钮被按下", Toast.LENGTH_SHORT).show();}if (id == R.id.disi){Toast.makeText(this, "第4个按钮被按下", Toast.LENGTH_SHORT).show();}return super.onContextItemSelected(item);
}
通过以上3步就能把上下文菜单调出来了,这个实现的是在屏幕中间弹出上下文菜单,还有一种是在屏幕顶部出现上下文菜单,这个在顶部出现上下文菜单的方法是:
想要实现上图这样的功能,为按钮设置上下文操作模式,要分为两步:
第一步:监听按钮的长按事件,设置上下文模式,调用回调函数。
findViewById(R.id.button).setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {startActionMode(cd);return true;}
});
第二步:重写创建菜单的方法:
@Override //重写创建菜单的方法public boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.menu,menu); //获取菜单对象return true;}
第三步:实现接口ActionMode CallBack,也就是重写回调函数:
ActionMode.Callback cd = new ActionMode.Callback() {// 创建 在启动上下文操作模式(startActionMode(Callback))时调用@Overridepublic boolean onCreateActionMode(ActionMode actionMode, Menu menu) {Toast.makeText(MainActivity.this, "上下文被创建", Toast.LENGTH_SHORT).show();getMenuInflater().inflate(R.menu.context,menu);return true;}// 准备 在创建方法后进行调用@Overridepublic boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {Toast.makeText(MainActivity.this, "上下文被准备", Toast.LENGTH_SHORT).show();return true;}//当选项被点击时调用@Overridepublic boolean onActionItemClicked(ActionMode Mode, MenuItem Item) {int id = Item.getItemId();if(id == R.id.diyi){Toast.makeText(MainActivity.this, "第1项被点击", Toast.LENGTH_SHORT).show();}if(id == R.id.dier){Toast.makeText(MainActivity.this, "第2项被点击", Toast.LENGTH_SHORT).show();}if(id == R.id.disan){Toast.makeText(MainActivity.this, "第3项被点击", Toast.LENGTH_SHORT).show();}if(id == R.id.disi){Toast.makeText(MainActivity.this, "第4项被点击", Toast.LENGTH_SHORT).show();}return true;}//上下文操作模式结束时被调用@Overridepublic void onDestroyActionMode(ActionMode actionMode) {Toast.makeText(MainActivity.this, "上下文操作结束了!", Toast.LENGTH_SHORT).show();}};
整体的代码:
package com.example.myapplication4;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});findViewById(R.id.textview1).setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {startActionMode(cd);return true;}});}@Override //重写创建菜单的方法public boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.menu,menu); //获取菜单对象return true;}ActionMode.Callback cd = new ActionMode.Callback() {@Overridepublic boolean onCreateActionMode(ActionMode actionMode, Menu menu) {getMenuInflater().inflate(R.menu.menu, menu);Toast.makeText(MainActivity.this, "创建成功", Toast.LENGTH_SHORT).show();return true;}@Overridepublic boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {Toast.makeText(MainActivity.this, "准备成功", Toast.LENGTH_SHORT).show();return true;}@Overridepublic boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {int id = menuItem.getItemId();if(id == R.id.diyi){Toast.makeText(MainActivity.this, "第一项被点击", Toast.LENGTH_SHORT).show();}else if(id == R.id.dier){Toast.makeText(MainActivity.this, "第2项被点击", Toast.LENGTH_SHORT).show();}else if(id == R.id.disan){Toast.makeText(MainActivity.this, "第3项被点击", Toast.LENGTH_SHORT).show();}return true;}@Overridepublic void onDestroyActionMode(ActionMode actionMode) {Toast.makeText(MainActivity.this, "被销毁", Toast.LENGTH_SHORT).show();}};}
通过以上的设置,就能实现上下文菜单的操作了。