美文网首页
Android悬浮窗口

Android悬浮窗口

作者: 122604 | 来源:发表于2020-06-02 20:53 被阅读0次

    1、最近在做视频通话功能,用到了悬浮窗。项目代码不能随便上,写一个简单的Demo记录下!更复杂的功能,自由发挥吧!!!

    20200602200022.gif

    2、废话不说,上代码;

    a、权限必须要;

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

    b、主要业务代码;

    import android.content.Context
    import android.content.Intent
    import android.graphics.PixelFormat
    import android.net.Uri
    import android.os.Build
    import android.os.Bundle
    import android.provider.Settings
    import android.util.DisplayMetrics
    import android.view.Gravity
    import android.view.MotionEvent
    import android.view.View
    import android.view.WindowManager
    import androidx.appcompat.app.AppCompatActivity
    import kotlinx.android.synthetic.main.activity_main2.*
    class Main2Activity : AppCompatActivity() {
        private var mWindowManager: WindowManager? = null
        private var mWindowParams: WindowManager.LayoutParams? = null
        private lateinit var mWindowView: View
        private val mMinWidht = dp2px(100F)
        private val mMinHeight = dp2px(150F)
        private val mMaxWidth = getMaxWidth()
        private val mMaxHeight = getMaxHeight()
        private val mStatusHeight = getStatusHeight()
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main2)
            btn_1.setOnClickListener {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
                    startActivity(
                        Intent(
                            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                            Uri.parse("package:${packageName}")
                        )
                    )
                } else {
                    openWindowView()
                }
            }
            btn_2.setOnClickListener {
                mWindowManager?.removeView(mWindowView)
            }
        }
    
    
        /**
         * 打开Window窗口
         */
        private fun openWindowView() {
            mWindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
            mWindowParams = WindowManager.LayoutParams()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mWindowParams!!.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                mWindowParams!!.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            }
            mWindowParams?.flags = (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                    or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
            mWindowParams?.format = PixelFormat.TRANSLUCENT
            mWindowParams?.width = mMinWidht
            mWindowParams?.height = mMinHeight
            mWindowParams?.gravity = Gravity.START or Gravity.TOP
            mWindowParams?.x = mMaxWidth - mMinWidht
            mWindowParams?.y = mStatusHeight
            mWindowView = View.inflate(this, R.layout.view_layout_window, null)
            mWindowView.findViewById<View>(R.id.v_event).setOnClickListener {
                /*点击放大、缩小事件*/
                mWindowParams?.width = if (mWindowParams?.width == mMinWidht) mMaxWidth else mMinWidht
                mWindowParams?.height =
                    if (mWindowParams?.height == mMinHeight) mMaxHeight else mMinHeight
                mWindowManager!!.updateViewLayout(mWindowView, mWindowParams)
            }
            mWindowView.setOnTouchListener(WindowOnTouchListener())
            mWindowManager!!.addView(mWindowView, mWindowParams)
    
        }
    
        /**
         * Window窗口触摸事件
         */
        inner class WindowOnTouchListener : View.OnTouchListener {
            private var mTouchStartX = 0
            private var mTouchStartY = 0
            private var mStartX = 0
            private var mStartY = 0
            override fun onTouch(v: View?, motionEvent: MotionEvent): Boolean {
                val action = motionEvent.action
                val x = motionEvent.x.toInt()
                val y = motionEvent.y.toInt()
                when (action) {
                    MotionEvent.ACTION_DOWN -> {
                        mTouchStartX = motionEvent.rawX.toInt()
                        mTouchStartY = motionEvent.rawY.toInt()
                        mStartX = x
                        mStartY = y
                    }
                    MotionEvent.ACTION_MOVE -> {
                        if (null != mWindowParams && null != mWindowManager) {
                            val mTouchCurrentX = motionEvent.rawX.toInt()
                            val mTouchCurrentY = motionEvent.rawY.toInt()
                            val tempX = mWindowParams!!.x + mTouchCurrentX - mTouchStartX
                            val tempY = mWindowParams!!.y + mTouchCurrentY - mTouchStartY
                            var newX: Int = -1
                            var newY: Int = -1
                            if (tempX >= 0 && tempX <= (mMaxWidth - mMinWidht)) {
                                newX = tempX
                                mTouchStartX = mTouchCurrentX
                            }
                            if (tempY >= mStatusHeight && tempY <= (mMaxHeight - mMinHeight)) {
                                newY = tempY
                                mTouchStartY = mTouchCurrentY
                            }
                            mWindowParams!!.x = if (newX == -1) mWindowParams!!.x else newX
                            mWindowParams!!.y = if (newY == -1) mWindowParams!!.y else newY
                            mWindowManager!!.updateViewLayout(mWindowView, mWindowParams)
                        }
                    }
                }
                return true
            }
        }
    
        /**
         * 屏幕宽度
         */
        private fun getMaxWidth(): Int {
            val windowManager = GitTestApplication.getApplication()
                .getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val outMetrics = DisplayMetrics()
            windowManager.defaultDisplay.getMetrics(outMetrics)
            return outMetrics.widthPixels
        }
    
        /**
         * 屏幕高度
         */
        private fun getMaxHeight(): Int {
            val windowManager =
                GitTestApplication.getApplication()
                    .getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val outMetrics = DisplayMetrics()
            windowManager.defaultDisplay.getMetrics(outMetrics)
            return outMetrics.heightPixels
        }
    
        /**
         * dp转换为px
         */
        private fun dp2px(dpValue: Float): Int {
            val scale: Float = GitTestApplication.getApplication().resources.displayMetrics.density
            return (dpValue * scale + 0.5f).toInt()
        }
    
        /**
         * 获取状态栏高度
         */
        private fun getStatusHeight(): Int {
            val resources = GitTestApplication.getApplication().resources
            val resourceId: Int = resources.getIdentifier("status_bar_height", "dimen", "android")
            return resources.getDimensionPixelSize(resourceId)
        }}
    

    c、view_layout_window.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/shape_radius_12_solid_000000">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="显示内容"
            android:textColor="#FFFFFFFF"
            android:textSize="18sp"
            android:textStyle="bold" />
    
        <View
            android:id="@+id/v_event"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="20dp"
            android:background="@drawable/shape_oval_solid_red_light" />
    </RelativeLayout>
    

    d、shape_oval_solid_red_light.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval">
        <solid android:color="@android:color/holo_red_light" />
    </shape>
    

    e、shape_radius_12_solid_000000.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <corners android:radius="12dp" />
        <solid android:color="#FF000000" />
    </shape>
    

    f、activity_main2.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical">
    
    
        <Button
            android:id="@+id/btn_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="打开" />
    
        <Button
            android:id="@+id/btn_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="关闭" />
    
    </LinearLayout>
    

    相关文章

      网友评论

          本文标题:Android悬浮窗口

          本文链接:https://www.haomeiwen.com/subject/dkypzhtx.html