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界面。

在这里插入图片描述

AndroidMainfest.xml

添加重启和关机的权限

<uses-permission android:name="android.permission.REBOOT" />
<uses-permission android:name="android.permission.SHUTDOWN" />

res/menu/main_menu.xml

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

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><itemandroid:id="@+id/action_restart"android:title="重启"android:icon="@drawable/ic_restart"app:showAsAction="never"/><itemandroid:id="@+id/action_shutdown"android:title="关机"android:icon="@drawable/ic_power_off"app:showAsAction="never"/>
</menu>

重启图标:drawable/ic_restart.xml

在这里插入图片描述

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"android:tint="?attr/colorControlNormal"><pathandroid:fillColor="@android:color/white"android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>

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

关机图标:drawable/ic_power_off.xml

在这里插入图片描述

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"android:tint="?attr/colorControlNormal"><pathandroid:fillColor="@android:color/white"android:pathData="M13,3h-2v10h2V3zM16.59,6.59L18,8c3.87,3.87 3.9,10.24 0.1,14.14 -3.79,3.9 -10.23,3.87 -14.12,-0.08C-0.1,18.1 -0.07,11.66 3.82,7.77l1.41,-1.41L4.2,5.2C-0.18,9.58 -0.16,17.03 4.3,21.4c4.47,4.36 11.91,4.35 16.37,-0.02 4.46,-4.38 4.47,-11.83 0.02,-16.2L16.59,6.59z"/>
</vector>

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

三个点图标:drawable/ic_more_vert.xml

在这里插入图片描述

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"><pathandroid:fillColor="@android:color/white"android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

activity_main.xml

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

<LinearLayout
...
...
<ImageViewandroid:id="@+id/menuButton"android:layout_width="40dp"android:layout_height="40dp"android:layout_marginStart="10dp"android:src="@drawable/ic_more_vert"android:padding="8dp"/>
</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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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 studio出现些许问题,未能实践成功,但具体步骤如下:

  1. AndroidManifest.xml
    添加shareuid属性

  2. build中选择如下选项
    在这里插入图片描述

  3. APK
    在这里插入图片描述

  4. 首次创建选Create new…
    在这里插入图片描述

  5. 创建一个.jks文件
    在这里插入图片描述

  6. 点击next

  7. 选择release版本
    在这里插入图片描述

  8. 点击create生产签名的apk

  9. 其他总结:
    在这里插入图片描述
    链接: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 这个是本地的签名文件路径

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92646.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92646.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/92646.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20250724-day21

Main Memory Database System&#xff08;MMDB&#xff09;&#xff1a;基于内存的数据库系统 File Database&#xff08;FDB&#xff09;&#xff1a;基于文件的数据库 Netware Database&#xff08;NDB&#xff09;&#xff1a;基于网络的数据库 daemon&#xff1a;守护进程 …

API是什么,如何保障API安全?

API&#xff08;应用程序编程接口&#xff09;是什么&#xff1f; API&#xff08;Application Programming Interface&#xff09;是不同软件系统之间通信的“桥梁”。它定义了应用程序如何请求服务、交换数据或调用功能&#xff0c;无需了解底层实现细节。例如&#xff0c;当…

深度分析Java多线程机制

Java 多线程是掌握高性能、高响应性应用程序开发的关键&#xff0c;它涉及到语言特性、JVM 实现、操作系统交互以及并发编程的核心概念。 核心目标&#xff1a; 充分利用现代多核 CPU 的计算能力&#xff0c;提高程序吞吐量&#xff08;单位时间内处理的任务量&#xff09;和响…

Android热修复实现方案深度分析

热修复的核心目标是在**不发布新版本、不重新安装、不重启应用&#xff08;或仅轻量级重启&#xff09;**的情况下&#xff0c;修复线上应用的 Bug 或进行小范围的功能更新&#xff0c;极大地提升用户体验和问题响应速度。 一、热修复的核心原理 无论哪种方案&#xff0c;其核心…

HTML前端颜色渐变动画完整指南

渐变动画已经成为现代网页设计中不可或缺的元素&#xff0c;它们不仅能为网站增添视觉吸引力&#xff0c;还能显著提升用户体验。通过巧妙运用CSS渐变动画&#xff0c;开发者可以创造出令人印象深刻的动态背景效果&#xff0c;而无需依赖图片或复杂的脚本。 渐变动画的魅力所在…

b-up:Enzo_mi:Transformer DETR系列

1.视频1&#xff1a;self-Attention&#xff5c;自注意力机制 &#xff5c;位置编码 &#xff5c; 理论 代码 注意&#xff1a; q-查询; k-商品标签&#xff1b; v-值&#xff08;具体商品&#xff09; * 不是指乘法&#xff0c;类似概念 a1:相似度&#xff1b; b1:总分 若想…

算法题(179):单调栈

审题&#xff1a; 本题是单调栈的模板题 补充&#xff1a;单调栈 单调栈中的数据始终保持单调递增或单调递减 使用情景&#xff1a;给定一个数组&#xff0c;要求寻找 1.某个数左侧&#xff0c;离他最近且值大于他的数 2.某个数左侧&#xff0c;离他最近且值小于他的数 3.某个数…

CF每日5题(1500-1600)

545C 贪心 1500 题意&#xff1a;给 n 棵树在一维数轴上的坐标 xix_ixi​ &#xff0c;以及它们的长度 hih_ihi​。现在要你砍倒这些树&#xff0c;树可以向左倒也可以向右倒&#xff0c;砍倒的树不能重合、当然也不能覆盖其他的树原来的位置&#xff0c;现在求最大可以砍倒的…

HW蓝队:天眼告警监测分析之Web攻击

Web攻击 信息泄露 敏感数据包括但不限于:口令、密钥、证书、会话标识、License、隐私数据(如短消息的内容)、授权凭据、个人数据(如姓名、住址、电话等)等&#xff0c;在程序文件、配置文件、日志文件、备份文件及数据库中都有可能包含敏感数据 信息收集方法 漏洞分类 备份文…

大腾智能国产3D CAD软件正式上架华为云云商店

深圳市大腾信息技术有限公司&#xff08;以下简称“大腾智能”&#xff09;与华为云达成深度合作&#xff0c;大腾智能CAD软件及配套服务通过了华为云在功能适配、安全可用、稳定高效等方面的严选商品认证&#xff0c;已正式上架华为云云商店&#xff0c;成为华为云云商店的联营…

论文复现-windows电脑在pycharm中运行.sh文件

1.更改终端路径&#xff08;前提&#xff1a;已下载git bash&#xff09;2.授权打开pycharm终端&#xff0c;输入 chmod x 文件名3.根据当前位置&#xff0c;运行.sh文件

开关电源安全保护电路:浪涌保护、过流保护、过压保护

开关电源安全保护电路:浪涌保护、过流保护、过压保护 引言 对于开关电源而言, 安全、可靠性历来被视为重要的性能之一. 开关电源在电气技术指标满足电子设备正常使用要求的条件下, 还要满足外界或自身电路或负载电路出现故障的情况下也能安全可靠地工作. 为此, 须有多种保护措…

C语言(十)

一、函数概述函数是面向过程编程思想的具体体现&#xff0c;主要作用&#xff1a;降低程序之间的耦合性提高代码的复用性和可维护性一个完整的 C 程序由**一个或多个程序模块&#xff08;源文件&#xff09;**组成。为便于开发与调试&#xff0c;通常会将代码拆分为多个源文件&…

QT项目-仿QQ音乐的音乐播放器(第二节)

目录 自定义控件&#xff1a; BtForm类中实现 BtForm上的动画效果 自定义控件&#xff1a; 该控件实际由&#xff1a;图⽚、⽂字、动画三部分组成。图⽚和⽂字分别⽤QLabel展⽰&#xff0c;动画部分内部实际为4 个QLabel。 ① 将BtForm的geometry的宽度和⾼度修改为200*35。…

【世纪龙科技】数字课程资源-新能源汽车概论

一、课程介绍本课程为通过项目任务式教学&#xff0c;全面系统的讲解了新能源汽车的基础知识及相关技能&#xff0c;培养和提高学生的动手能力和理论知识的工程应用能力。以典型工作任务带动知识与技能的学习&#xff0c;采用项目教学培养学生的岗位技能、学习能力和职业素养。…

iOS Core Data 本地数据库 使用详解:从模型关系到数据操作

一、引言&#xff1a;Core Data&#xff0c;在本地数据持久化中的地位在 iOS 开发中&#xff0c;本地数据存储几乎是每一个 App 都绕不开的问题。无论是缓存用户信息、离线浏览内容&#xff0c;还是记录用户操作历史&#xff0c;一个合适的数据持久化方案都能大大提升应用的体验…

Java-79 深入浅出 RPC Dubbo 动态路由架构详解:从规则设计到上线系统集成

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-30-新发布【1T 万亿】参数量大模型&#xff01;Kim…

Linux内核中动态内存分配函数解析

在C语言中&#xff0c;动态内存分配通常用于在运行时申请内存。在内核编程中&#xff0c;动态内存分配与用户空间有所不同&#xff0c;因为内核需要更谨慎地处理内存&#xff0c;且不能使用用户空间的库&#xff08;如glibc&#xff09;。下面我们将详细分析Linux内核中动态申请…

Next.js 中配置不同页面布局方案

在 Next.js 应用中&#xff0c;你可以通过多种方式实现某些页面全屏、某些页面带菜单/页眉/页脚的需求。以下是几种实现方案&#xff1a; 方案一&#xff1a;使用多个布局组件 1. 创建不同的布局组件 // app/default-layout.tsx import Header from /components/header; import…

Spring Boot 使用外置 Servlet 容器:从配置到部署全指南

在 Spring Boot 开发中&#xff0c;我们通常使用嵌入式 Servlet 容器&#xff08;如 Tomcat&#xff09;&#xff0c;它能将应用打包成可执行 JAR&#xff0c;简化部署流程。但在某些场景下&#xff08;如需要支持 JSP、复杂的容器定制或企业级部署规范&#xff09;&#xff0c…