一、當AlertDialog顯示的時候,Activity的焦點被搶去,如何避免AlertDialog 被搶焦點呢?
1、設置去掉按鍵退出
去掉 setCancelable(true)
dialog.setCanceledOnTouchOutside(true);
2、setFlags FLAG_NOT_FOCUSABLE
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
window.setGravity(Gravity.CENTER); window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
dialog.show();
WindowManager.LayoutParams:
int TYPE_SYSTEM_ALERT Window type: system window, such as low power alert.(系統窗體,例如低電量警告提示框)
int TYPE_SYSTEM_OVERLAY Window type: system overlay windows, which need to be displayed on top of everything else.(系統覆蓋窗體,哪個需要顯示在最前的)
TYPE_SYSTEM_ALERT跟TYPE_SYSTEM_OVERLAY的區別
system_alert窗口可以獲得焦點,響應操作
system_overlay窗口顯示的時候焦點在後面的Activity上,仍舊可以操作後面的Activity
清單文件manifest中需要相應的permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
以下兩種方式顯示出來的窗口都不會激發當前Activity的onPause()事件。
1. Service 創建窗體
private void showSystemDialog() {
/* create ui dialog */
View v = View.inflate(mContext, R.layout.serveice_dialog, null);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setView(v);
dialog = alertDialog.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
dialog.show();
**** 注意dialog 在執行show方法之後,才能調整dialog的大小以及更新數據 ****
/* set size & pos */
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if (display.getHeight() > display.getWidth()) {
//lp.height = (int) (display.getHeight() * 0.5);
lp.width = (int) (display.getWidth() * 1.0);
} else {
//lp.height = (int) (display.getHeight() * 0.75);
lp.width = (int) (display.getWidth() * 0.5);
}
d.getWindow().setAttributes(lp);
/* update ui data */
lv = (ListView) d.getWindow().findViewById(R.id.listview);
SimpleAdapter adapter = new SimpleAdapter(mContext, getListData(), R.layout.list_item,
new String[]{"item_text", "item_img"},
new int[]{R.id.item_text, R.id.item_img});
lv.setAdapter(adapter);
/* set listener */
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int pos,
long id) {
d.dismiss();
}
});
}
2、直接使用WindowManager.addView()在後臺直接顯示窗口
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDesktopLayout = inflater.inflate(R.layout.volume_panel, null);
// 取得系統窗體
mWindowManager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
// 窗體的佈局樣式
mLayoutParams = new WindowManager.LayoutParams();
// 設置窗體顯示類型――TYPE_SYSTEM_ALERT(系統提示)
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
// 設置窗體焦點及觸摸:
// FLAG_NOT_FOCUSABLE(不能獲得按鍵輸入焦點)
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
// 設置顯示的模式
mLayoutParams.format = PixelFormat.RGBA_8888;
// 設置對齊的方法
mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
// 設置窗體寬度和高度
mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
// 設置窗體顯示的位置,否則在屏幕中心顯示
mLayoutParams.x = 50;
mLayoutParams.y = 50;
mWindowManager.addView(mDesktopLayout, mLayoutParams);
3、Activity 關係
回退黑屏
dumpsys acitivity