前言
你會發現QQ視頻的時候,就算手機回到主頁,視頻小模塊依舊能懸浮在桌面上。還有當年很火的各種手機殺毒軟件的桌面小助手,總能在呆在桌面。這種懸浮窗的操作就需要用到Window。
效果
gif圖看著有點兒卡,其實實際上還是很流暢的。
Window
Window即窗口,是個抽象類,具體實現就是PhoneWindow,對就是那個裝著DecorView的PhoneWindow。
Window整體分三種類型:應用Window、子Window、系統Window。
每種Window類型又能分多個層級:
層級高的Window會覆蓋層級低的Window,跟Android5.0引入的Z軸類似。
權限
Android6.0以上,如果要用系統Window,我們需要申請懸浮窗權限。畢竟WindowManager.LayoutParams.TYPE_TOAST權限限制太多了。
Manifests:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
判斷是否有懸浮窗權限:
Settings.canDrawOverlays(this)
申請權限:
Intent intent = new Intent(); intent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:"+getPackageName())); startActivity(intent);
WindowManager
View想要呈現出來,必須要通過Window,但是我們無法直接操作Window,需要用到WindowManager。
WindowManager 獲取對象:
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager 繼承了 ViewManager,操作View總共只有這三個方法:
public interface ViewManager { /** * Assign the passed LayoutParams to the passed View and add the view to the window. * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming * errors, such as adding a second view to a window without removing the first view. * <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a * secondary {@link Display} and the specified display can't be found * (see {@link android.app.Presentation}). * @param view The view to be added to this window. * @param params The LayoutParams to assign to view. */ public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); }
分別是增加View、更新View和刪除View。
WindowManager參數設置
由上可知:addView 和 updateViewLayout時,需要用到LayoutParams。
這里來舉個栗子:
wParamsTop = new WindowManager.LayoutParams(); wParamsTop.width = WindowManager.LayoutParams.WRAP_CONTENT; wParamsTop.height = WindowManager.LayoutParams.WRAP_CONTENT; //初始化坐標 wParamsTop.x = 0; wParamsTop.y = 0; //彈窗類型為系統Window wParamsTop.type = WindowManager.LayoutParams.TYPE_PHONE; //以左上角為基準 wParamsTop.gravity = Gravity.START | Gravity.TOP; wParamsTop.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //如果不加,背景會是一片黑色。 wParamsTop.format = PixelFormat.RGBA_8888;
type參數上面講過了,這里來看看主要的flag參數。
Demo
利用ActivityLifecycleCallbacks實現了前后臺的監聽,切換到后臺時隱藏了懸浮窗。感興趣的可以看看這篇文章:ActivityLifecycleCallbacks 判斷APP是否在前臺。
上面的logo和下面的viewpager是兩個view ,通過調用兩次addview實現的效果。
源碼下載:Android利用WindowManager實現懸浮窗
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。