> 技术文档 > 【Android】Popup menu:弹出式菜单

【Android】Popup menu:弹出式菜单


Popup menu:弹出式菜单

PopupMenu,弹出菜单,一个模态形式展示的弹出风格的菜单,绑在在某个View上,一般出现在被绑定的View的下方(如果下方有空间)。

注意:弹出菜单是在API 11和更高版本上才有效的。

核心步骤:

(1)通过PopupMenu的构造函数实例化一个PopupMenu对象,需要传递一个当前上下文对象以及绑定的View。

(2)调用PopupMenu.setOnMenuItemClickListener()设置一个PopupMenu选项的选中事件。

(3)使用MenuInflater.inflate()方法加载一个XML文件到PopupMenu.getMenu()中。

(4)在需要的时候调用PopupMenu.show()方法显示。

需求

点击右上角的\"…“,下拉出来\"重启\"和\"关闭”,点击\"重启\"或者\"关闭\",弹出一个弹窗确认是否需要重启或者关闭设备;再点击确定,就会重启或者关机该设备;点击取消,什么都不做,继续保持再主launcher界面。

【Android】Popup menu:弹出式菜单

AndroidMainfest.xml

添加重启和关机的权限

res/menu/main_menu.xml

创建main_menu.xml文件,menu中包含item(重启和关机);

  

重启图标:drawable/ic_restart.xml

【Android】Popup menu:弹出式菜单

 

tips:去掉android:tint=“?attr/colorControlNormal\"这个属性可以让图标变成白色,也就是android:fillColor=”@android:color/white\"这个属性可以生效。

关机图标:drawable/ic_power_off.xml

【Android】Popup menu:弹出式菜单

 

tips:去掉android:tint=“?attr/colorControlNormal\"这个属性可以让图标变成白色,也就是android:fillColor=”@android:color/white\"这个属性可以生效。

三个点图标:drawable/ic_more_vert.xml

【Android】Popup menu:弹出式菜单

 

activity_main.xml

此文件中指出三个点图标的位置

<LinearLayout......

android:src=\"@drawable/ic_more_vert\"是三个点的图标,将三个点的图标显示在LinearLayout中

MainActivity.java

  1. 在OnCreate方法中绑定三个点图标的监听事件

     protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupClickListeners(); }
  2. 监听

    findViewById(R.id.menuButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {  showPopupMenu(view); } });

R.id.menuButton是activity_main.xml中设置的id,setOnClickListener监听点击事件,当点击时触发showPopupMenu(view)

showPopupMenu方法

 private void showPopupMenu(View view) { // View当前PopupMenu显示的相对View的位置 PopupMenu popupMenu = new PopupMenu(this, view); // menu布局 popupMenu.getMenuInflater().inflate(R.menu.main_menu, popupMenu.getMenu()); // menu的item点击事件 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {  @Override  public boolean onMenuItemClick(MenuItem item) {  if (item.getItemId() == R.id.action_restart) {  showConfirmationDialog(\"重启设备\", \"您确定要重启设备吗?\", item.getItemId());  } else if (item.getItemId() == R.id.action_shutdown) {  showConfirmationDialog(\"关闭设备\", \"您确定要关闭设备吗?\", item.getItemId());  }  return false;  } });// // PopupMenu关闭事件// popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {// @Override// public void onDismiss(PopupMenu menu) {// Toast.makeText(getApplicationContext(), \"关闭PopupMenu\", Toast.LENGTH_SHORT).show();// }// }); popupMenu.show(); }

当点击重启或者关机按钮时触发事件

popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == R.id.action_restart) { showConfirmationDialog(\"重启设备\", \"您确定要重启设备吗?\", item.getItemId()); } else if (item.getItemId() == R.id.action_shutdown) { showConfirmationDialog(\"关闭设备\", \"您确定要关闭设备吗?\", item.getItemId()); } return false; } });

showConfirmationDialog

private void showConfirmationDialog(String title, String message, int itemId) { new AlertDialog.Builder(this) .setTitle(title) .setMessage(message) .setPositiveButton(\"确定\", (dialog, which) -> { dialog.cancel(); if (R.id.action_restart == itemId) {  restartDevice(); } else {  shutdownDevice(); } }) .setNegativeButton(\"取消\", (dialog, which) -> { }) .setIcon(R.id.action_restart == itemId ? R.drawable.ic_restart : R.drawable.ic_power_off) .show();}

restartDevice

private void restartDevice() { try { // 需要系统应用签名 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); pm.reboot(null); } catch (Exception e) { Toast.makeText(this, \"重启失败: \" + e.getMessage(), Toast.LENGTH_LONG).show(); }}

shutdownDevice

private void shutdownDevice() { try { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); Method shutdownMethod = pm.getClass().getMethod(\"shutdown\", boolean.class, String.class, boolean.class); shutdownMethod.invoke(pm, false, null, false); // 执行关机 } catch (Exception e) { Toast.makeText(this, \"关机失败: \" + e.getMessage(), Toast.LENGTH_LONG).show(); }}

最终效果

点击三个点按钮
【Android】Popup menu:弹出式菜单
点击重启或者关机
【Android】Popup menu:弹出式菜单
点击取消回到主界面;
点击确定重启或者关机执行操作。

注意:普通权限可以执行重启操作,但是不能执行关机操作,关机操作需要系统签名获取系统权限。

签名总结

由于Android studio出现些许问题,未能实践成功,但具体步骤如下:

  1. AndroidManifest.xml
    添加shareuid属性

  2. build中选择如下选项
    【Android】Popup menu:弹出式菜单

  3. APK
    【Android】Popup menu:弹出式菜单

  4. 首次创建选Create new…
    【Android】Popup menu:弹出式菜单

  5. 创建一个.jks文件
    【Android】Popup menu:弹出式菜单

  6. 点击next
    【Android】Popup menu:弹出式菜单

  7. 选择release版本
    【Android】Popup menu:弹出式菜单

  8. 点击create生产签名的apk

  9. 其他总结:
    【Android】Popup menu:弹出式菜单
    链接:https://blog.csdn.net/Sunxiaolin2016/article/details/100891402

命令:jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore path/to/your/keystore.keystore your_app.apk your_alias_name

path/to/your/keystore.keystore 这个是本地的签名文件路径