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
-
在OnCreate方法中綁定三個點圖標的監聽事件
protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setupClickListeners();}
-
監聽
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出現些許問題,未能實踐成功,但具體步驟如下:
-
AndroidManifest.xml
添加shareuid屬性 -
build中選擇如下選項
-
APK
-
首次創建選Create new…
-
創建一個.jks文件
-
點擊next
-
選擇release版本
-
點擊create生產簽名的apk
-
其他總結:
鏈接: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 這個是本地的簽名文件路徑