位址
http://blog.csdn.net/xiangyong_1521/article/details/78401755
目錄
- 關于Window/WindowManagerService的簡介
- ViewManager和WindowManager的實作
- 舉例實作
- 附
關于Window/WindowManagerService的簡介
- WindowManagerService
先來看WindowManagerService,從此圖可以得知,它是位于Framework層的視窗管理服務,職責就是管理系統中的所有視窗,視窗的本質是什麼呢?其實就是一塊顯示區域,在 Android 中就是繪制的畫布:Surface,當一塊 Surface 顯示在螢幕上時,就是使用者所看到的視窗了。WindowManagerService 添加一個視窗的過程,其實就是 WindowManagerService 為其配置設定一塊 Surface 的過程,一塊塊的 Surface 在 WindowManagerService 的管理下有序的排列在螢幕上
- Window
Window 是一個抽象類,表示一個視窗,它的具體實作類是 PhoneWindow,實作位于 WindowManagerService 中;Window 有三種類型Window 是分層的,每個 Window 都有對應的 z-ordered(處在這些疊加視窗中的位置),層級大的會覆寫在層級小的 Window 上面,這和 HTML 中的 z-index 概念是完全一緻的。在三種 Window 中,應用 Window 層級範圍是 1~99,子 Window 層級範圍是 1000~1999,系統 Window 層級範圍是 2000~2999,我們可以用一個表格來直覺的表示
- 應用 Window:應用類 Window 對應一個 Acitivity;
- 子 Window :子 Window 不能單獨存在,需要依附在特定的父 Window 中,比如常見的一些 Dialog 就是一個子 Window;
- 系統 Window:系統 Window是需要聲明權限才能建立的 Window,比如 Toast 和系統狀态欄都是系統 Window。
Window 層級 應用 1-99 子 1000-1999 系統 2000-299 這些層級是對應的WindowManager.LayoutParams 的 type 參數,如下圖:
ViewManager和WindowManager的實作
- ViewManager
我們對 Window 的操作是通過 WindowManager 來完成的,WindowManager繼承于 ViewManagerWindowManager 是一個接口,它繼承自隻有三個方法的 ViewManager 接口:
- public interface ViewManager
- {
- /**
- * 讓您添加和删除子視圖到活動的接口。得到一個執行個體
- */
- public void addView(View view, ViewGroup.LayoutParams params);
- public void updateViewLayout(View view, ViewGroup.LayoutParams params);
- public void removeView(View view);
- }
三個方法其實就是 WindowManager 對外提供的主要功能,即添加 View、更新 View 和删除 View
- WindowManager實作
- public void show(){
- if (mContentView != null) {
- wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
- wmParams.format = PixelFormat.RGBA_8888;
- wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- wmParams.alpha = 1.0F;
- wmParams.gravity = Gravity.TOP | Gravity.LEFT;
- wmParams.x = 0;
- wmParams.y = 0;
- wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
- wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- wm.addView(mContentView, wmParams);
- bShow=true;
- }
- }
- 權限:<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
舉例實作
- service
- /*
- * ervice中随時監聽限制條件的變化以調動懸浮開關
- */
- private Timer mTimer = null;
- private TimerTask mTimerTask = null;
- private void upTime() {//開啟一個線程,在service中随時監聽限制條件的變化
- this.mTimerTask=new TimerTask() {
- @Override
- public void run() {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if () {//限制條件
- MyWindowManager.createwinm(getApplicationContext());//開啟視窗
- }
- }
- });
- }else
- if () { //限制條件
- MyWindowManager.removewinm(getApplicationContext());//關閉視窗
- }
- };
- this.mTimer.schedule(mTimerTask, 300, 300);
- }
- WindowManager
- /*
- * 定義一個實作WindowManager的類,所有需要懸浮的界面可以在此類中定義windowManager
- */
- public class MyWindowManager {
- public static CarDoor carDoor;
- public static LayoutParams doorParams;
- public static void createwinm(Context context) {
- WindowManager windowManager = getWindowManager(context);
- if (carDoor == null) {
- carDoor = new CarDoor(context);
- if (doorParams == null) {
- doorParams = new LayoutParams();
- doorParams.type = LayoutParams.TYPE_PHONE;
- doorParams.format = PixelFormat.RGBA_8888;
- doorParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
- | LayoutParams.FLAG_NOT_FOCUSABLE;
- doorParams.gravity = Gravity.CENTER;
- doorParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
- doorParams.width = carDoor.viewWidth;
- doorParams.height = carDoor.viewHight;
- doorParams.x = 0;
- doorParams.y = 0;
- }
- carDoor.setParams(doorParams);
- windowManager.addView(carDoor, doorParams);
- carDoor.updateViewPosition();
- }
- }
-
- public static void removewinm(Context context) {
- if (carDoor != null) {
- carDoor.mTimerTask.cancel();
- WindowManager windowManager = getWindowManager(context);
- windowManager.removeView(carDoor);
- carDoor = null;
-
- }
- }
- }
- CarDoor
- /*
- * 懸浮界面要要實作什麼功能在此類定義就好了;
- */
- public class CarDoor extends LinearLayout {
- public CarDoor(Context context) {
- super(context);
- windowManager=(WindowManager) context.getSystemService(context.WINDOW_SERVICE);
- LayoutInflater.from(context).inflate(R.layout.layout_cardoor,this);
- View view=findViewById(R.id.layout_cardoor1);
- viewWidth=view.getLayoutParams().width;
- viewHight=view.getLayoutParams().height;
- initView(view);
- initData();
- test1();
- }
- }
附
筆記26 | 總結Android的擷取系統時間的幾種方法
筆記25 | 通過自定義VIEW實作一個圓盤轉動UI
筆記24 | 一個中間打開界面的動畫
筆記23 | 複習了/而/做......而的幾種循環用法
筆記22 | 學習整理開源APP(BaseAnimation)程式源碼“中的通訊錄效果(三)
結束