1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package cn.flightfeather.thirdapp.view
 
import android.content.Context
import android.graphics.PixelFormat
import android.os.IBinder
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.widget.PopupWindow
import org.jetbrains.anko.windowManager
 
/**
 * @author riku
 * Date: 2020/8/28
 */
class PopupWindowWithMask(private val context: Context) : PopupWindow(context) {
 
    private var windowManager: WindowManager? = null
    private var maskView: View? = null
 
    init {
        windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    }
 
    override fun showAtLocation(parent: View?, gravity: Int, x: Int, y: Int) {
        addMask(parent?.windowToken)
        super.showAtLocation(parent, gravity, x, y)
    }
 
    override fun dismiss() {
        removeMask()
        super.dismiss()
    }
 
    private fun addMask(token: IBinder?) {
        val wl: WindowManager.LayoutParams = WindowManager.LayoutParams()
        wl.width = WindowManager.LayoutParams.MATCH_PARENT
        wl.height = WindowManager.LayoutParams.MATCH_PARENT
        wl.format = PixelFormat.TRANSLUCENT //不设置这个弹出框的透明遮罩显示为黑色
        wl.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL //该Type描述的是形成的窗口的层级关系
        wl.token = token //获取当前Activity中的View中的token,来依附Activity
        maskView = View(context)
        maskView?.setBackgroundColor(0x7f000000)
        maskView?.fitsSystemWindows = false
        maskView?.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                removeMask()
                return@OnKeyListener true
            }
            false
        })
        /**
         * 通过WindowManager的addView方法创建View,产生出来的View根据WindowManager.LayoutParams属性不同,效果也就不同了。
         * 比如创建系统顶级窗口,实现悬浮窗口效果!
         */
        windowManager?.addView(maskView, wl)
    }
 
    private fun removeMask() {
        if (null != maskView) {
            windowManager?.removeViewImmediate(maskView)
            maskView = null
        }
    }
}