IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 安卓悬浮窗两种实现与踩坑 -> 正文阅读

[移动开发]安卓悬浮窗两种实现与踩坑

第一种 需要权限的悬浮窗:

权限:

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

禁用事件:

layoutParams.flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

不禁用事件:

//不影响悬浮覆盖的view所以事件,单纯的是个盖板,就像护眼宝一样
layoutParams.flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

全屏设置:

layoutParams.flags =
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
?//屏幕不限制 ? 高度layoutParams.height = 5000超过手机屏幕高度都可
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT+5000;

不全屏(状态栏不会被覆盖):

layoutParams.flags =
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
?//屏幕不限制 ? 高度layoutParams.height = 5000超过手机屏幕高度都可
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;

组合 1 全屏,不禁用事件:

效果:不影响手机滑动以及任何操作

        layoutParams.flags =
                //不影响悬浮覆盖的view所以事件,单纯的是个盖板,就像护眼宝一样
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

                //屏幕不限制   高度layoutParams.height = 5000超过手机屏幕高度都可
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;


        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
//屏幕不限制   高度layoutParams.height = 5000超过手机屏幕高度都可
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT+5000;

代码:

package com.hlz.mytools;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.provider.Settings;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;

import static android.content.Context.WINDOW_SERVICE;


public class FloatWindowManager {
    private volatile static FloatWindowManager instance = null;
    private Activity mAct;
    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;
    private View view;


    private FloatWindowManager(Activity activity) {
        this.mAct = activity;
        init(mAct);
    }

    private void init(Activity activity) {
        windowManager = (WindowManager) activity.getSystemService(WINDOW_SERVICE);
        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.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        }
        layoutParams.format = PixelFormat.RGBA_8888;
        layoutParams.gravity = Gravity.CENTER;
        layoutParams.alpha = 0.5f;
//        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.flags =
                //不影响悬浮覆盖的view所以事件,单纯的是个盖板,就像护眼宝一样
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

                //屏幕不限制   高度layoutParams.height = 5000超过手机屏幕高度都可
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;

//        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
//                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
//                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
//
//                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
//                        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;

        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT+5000;
    }

    public static FloatWindowManager getInstance(Activity mAct) {
        if (instance == null) {
            synchronized (FloatWindowManager.class) {
                if (instance == null) {
                    instance = new FloatWindowManager(mAct);
                }
            }
        }
        return instance;

    }



    @SuppressLint("NewApi")
    public void showFloatingWindow() {
        if (Settings.canDrawOverlays(mAct)) {
            view = new View(mAct.getApplicationContext());
            view.setBackgroundColor(Color.BLACK);
            windowManager.addView(view, layoutParams);
        }
    }

    public void hideFloatingWindow() {
        if (null != view && windowManager != null) {
            windowManager.removeViewImmediate(view);
        }

    }
}

第二种 不需要权限悬浮:

用kotlin实现代码:

package com.bjx.bjxcommon.view

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import java.lang.ref.WeakReference


class FloatViewManager constructor(activity: Activity, val isOpen: Boolean = false) {
    private var view: View? = null
    private var isFirstInit = true
    private val context by lazy { WeakReference(activity).get() }

    init {
        if (isOpen) {
            init()
        }
    }

    @SuppressLint("NewApi")
    fun init() {
        if (!isFirstInit) return
        isFirstInit = false
        context?.registerActivityLifecycleCallbacks(object :
            Application.ActivityLifecycleCallbacks {

            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {

            }


            override fun onActivityStarted(activity: Activity) {

            }


            override fun onActivityResumed(activity: Activity) {
                addView()
            }


            override fun onActivityPaused(activity: Activity) {

            }


            override fun onActivityStopped(activity: Activity) {

            }


            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

            }


            override fun onActivityDestroyed(activity: Activity) {
                view?.let {
                    removeView(it)
                }
                view = null
                context?.unregisterActivityLifecycleCallbacks(this)
            }
        })
    }

    fun update() {

    }

    fun addView() {
        if (isAdd()) return
        context?.let { context ->
            view = View(context)
            view?.let {
                it.setBackgroundColor(Color.BLACK)
                it.alpha = 0.4f
                val vg = context.window.decorView
                when (vg) {
                    is ViewGroup -> {
                        vg.addView(
                            it,
                            ViewGroup.LayoutParams(
                                ViewGroup.LayoutParams.MATCH_PARENT,
                                ViewGroup.LayoutParams.MATCH_PARENT
                            )
                        )
                    }
                }
            }
        }

    }

    fun removeView(view: View) {
        context?.let {
            val vg = it.window.decorView
            when (vg) {
                is ViewGroup -> {
                    if (isAdd()) {
                        vg.removeView(view)
                    }
                }
            }
        }
    }

    fun isAdd(): Boolean {
        if (context == null) return false
        val vg = context!!.window.decorView
        when (vg) {
            is ViewGroup -> {
                if (vg.childCount > 0) {
                    for (i in 0..vg.childCount - 1) {
                        val v = vg.getChildAt(i)
                        if (v == view) {
                            return true
                        }
                    }
                }
            }
        }
        return false
    }
}

在BaseActivity中调用:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

//FloatViewManager 内部会自动注销回收,无需在Activity中释放了
        FloatViewManager(this,true)
    }

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:45:30  更:2021-07-31 16:48:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 1:48:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码