Android利用WindowManager實現懸浮窗

不廢話,四步走:

1、首先要聲明懸浮窗口權限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>

2、引導用戶打開懸浮窗權限:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.canDrawOverlays(this)) {
        showTip("請先打開懸浮窗權限");
        startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);
    } else {
        //有權限了,可以用service或者直接用第三步開啓懸浮窗
    }
}

3、初始化懸浮窗:

private void initFloatingWindow() {
    if (Settings.canDrawOverlays(this)) {
        // 獲取WindowManager服務
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        //FloatView爲自定義的懸浮窗控件,亦可使用Button、ImageView之類的控件
        floatView = new FloatView(getApplicationContext());
        // 設置LayoutParam
        layoutParams = new WindowManager.LayoutParams();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
        // 實現懸浮窗可以移動的屬性(把這個值改成其他值可以操作懸浮窗底下的內容)
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.format = PixelFormat.TRANSPARENT;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.gravity = Gravity.CENTER;
        layoutParams.x = 0;
        layoutParams.y = 0;

        //todo
        //對你的懸浮窗做一些點擊或移動事件的處理
        
    }
}

layoutParams.flags的值選擇參考:https://www.jianshu.com/p/c91448e1c7d1

 

4、顯示和隱藏懸浮窗:

//顯示懸浮窗(添加懸浮窗控件)
windowManager.addView(floatView, layoutParams);


//隱藏懸浮窗(移除懸浮窗控件)
windowManager.removeView(floatView);


//更新懸浮窗控件佈局(對懸浮窗做修改之後調用)
windowManager.updateViewLayout(floatView, layoutParams);

 

至於懸浮控件的移動,懸浮窗控件設置一個OnTouchListener事件:

floatView.setOnTouchListener(new View.OnTouchListener() {
            private int x;
            private int y;

            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        x = (int) event.getRawX();
                        y = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int nowX = (int) event.getRawX();
                        int nowY = (int) event.getRawY();
                        int movedX = nowX - x;
                        int movedY = nowY - y;
                        x = nowX;
                        y = nowY;
                        layoutParams.x = layoutParams.x + movedX;
                        layoutParams.y = layoutParams.y + movedY;

                        // 更新懸浮窗控件佈局
                        windowManager.updateViewLayout(floatView, layoutParams);
                        break;
                    default:
                        break;
                }
                return false;
            }
        });

但是這樣實現的卻是整屏控制懸浮窗的移動,並不能很好的實現在懸浮窗上面拖動的效果,這個我還得再研究研究,也望各位大佬指點指點。

 

完。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章