2019独角兽企业重金招聘Python工程师标准>>>

touch here android在WindowManager添加View 作者:feiyangxiaomi

[TOC]

#1. 事情的起因 项目的驱动,希望提供一个弹窗,这个弹窗的特点是:

  • 非阻塞试弹窗,弹窗弹出的时候,点击弹窗外的屏幕区域,--不选PopupWindow(开源项目QuickAction不能用)
  • 弹窗需要内部能够点击某一项并做出相应,--不选Toast

此时考虑在界面上加入一个View,通过WindowManager.addView方法去添加弹出图层,这里先贴出一个图,看一下这个效果是否是你的菜: //截图

#2. 为什么选择WindowManager.addView WindowManager用来在应用与window之间的管理接口,管理窗口顺序,消息等。对于windowManager来说一个系统只有一个,它是由系统底层实现的,用于负责调度当前显示那个窗口,消息处理我们获得一个windowManager的方式如下:

WindowManager windowManager = (WindowManager)context().getSystemService(Context.WINDOW_SERVICE);

调用比较简单。

#3.代码实现 把这个弹窗叫做PopupAction,后面统一为这个称呼。 ##显示PopupAction代码

    /*** Show quick menu popup. Popup is automatically positioned, on top of anchor view. Calc of anchor and mRootView* view for look out the poosition. Every side margin of 10dp and the arrow at the top of anchor.* * @param context the global information about an applicaion environment* @param anchor view of call for* @param actions action list items {@link #addActionItem(List)}*/public void show(Context context, View anchor, List<ActionItem> actions) {mContext = context;if (mContext == null) {Log.i("MenuDialog", "context is null");return;}int xPos;int yPos;int arrowPos;int[] location = new int[2];//添加菜单项addActionItem(actions);mShowAction = true;//计算要弹出的位置anchor.getLocationOnScreen(location);Rect anchorRect =new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[1] + anchor.getHeight());int rootHeight = mRootView.getMeasuredHeight();int rootWidth = mRootView.getMeasuredWidth();xPos = anchorRect.centerX() - (rootWidth / 2);//对弹窗靠近左边和右边的处理if (xPos < 20) {xPos = 20;}DisplayMetrics dm = mContext.getResources().getDisplayMetrics();if ((dm.widthPixels - anchorRect.centerX()) < rootWidth / 2) {xPos = dm.widthPixels - rootWidth - 20;}arrowPos = anchorRect.centerX() - xPos;yPos = anchorRect.top - rootHeight;//设置箭头位置showArrow((R.id.arrow_down), arrowPos);//添加图层弹窗android.view.WindowManager.LayoutParams params =(android.view.WindowManager.LayoutParams) mRootView.getLayoutParams();params.x = xPos;params.y = yPos;mWM.addView(mParentView, params);mParentView.addView(mRootView);mParentView.setOnTouchListener(this);//设置弹出动画Animation animationUp = AnimationUtils.loadAnimation(mContext, R.anim.grow_from_bottom);mRootView.startAnimation(animationUp);}

其中初始化View,添加菜单项和设置点击菜单项的点击回调,参考QuickAction的代码,这里不再介绍。

#4.本文的目标点 ##WindowManager和WindowManager.LayoutParams

  1. 添加的view不显示,引出WindowManager.LayoutParams用什么type?
  2. 属性WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,如何响应点击outside和back键盘?可以看下stackoverflow很有意思
  3. 属性WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY能不能用? 对于WindowManager.LayoutParams配置代码:
   mParams = new WindowManager.LayoutParams();mParams.height = LayoutParams.WRAP_CONTENT;mParams.width = LayoutParams.WRAP_CONTENT;mParams.format = PixelFormat.TRANSLUCENT;mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;mParams.flags =WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;mParams.gravity = Gravity.TOP | Gravity.LEFT;mRootView.setLayoutParams(mParams);

可以看到这里使用的type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;,后面介绍一下几种类型。 flag使用

  • LayoutParams.FLAG_NOT_TOUCH_MODAL表示可以点击弹窗之外的屏幕区域,这是必须的。
  • LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH表示可以监听外部点击事件,这时候可以dismiss掉当前的弹窗,也是必需的。
  • WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 表示当前弹窗捕获得焦点,但能点击,非常重要。不然键盘区域的所有touch事件都会收不到。

|Constants|| |---|--| |TYPE_ACCESSIBILITY_OVERLAY|窗口重叠仅由AccessibilityService截取用户交互,而不改变窗口的无障碍服务可以内省。| |TYPE_APPLICATION|应用窗口| |TYPE_APPLICATION_ATTACHED_DIALOG|和TYPE_APPLICATION_PANEL类似,但是不作为一个应用的一部分,显示在窗口的顶层| |TYPE_APPLICATION_PANEL|应用顶层图层| |TYPE_APPLICATION_MEDIA|播放器图层| |TYPE_APPLICATION_STARTING|应用开始事的图层| |TYPE_APPLICATION_SUB_PANEL|应用子面板| |TYPE_PHONE |电话图层,部分手机无法使用,已测试| |~|| |TYPE_SYSTEM_ALERT|系统通知,使用时发现该图层会独立在应用之上| |TYPE_SYSTEM_DIALOG|系统对话框,使用时发现该图层会独立在应用之上| |TYPE_SYSTEM_ERROR|系统错误,非常靠上| |TYPE_SYSTEM_OVERLAY|系统普通图层| |TYPE_TOAST|系统toast| 参考网上实例的时候,建议不要采用系统图层,网上的好多实例都是采用:TYPE_SYSTEM_ALERT,不合理。

###WindowManager.addView的动画效果 动画部分可以采用: WindowManager.windowAnimations=R.style.xxx但是不建议使用,该资源在官网上说是鼻息使用系统资源,因为window manager拿到应用的资源。 那怎么办?参考:WindowManager with Animation (is it possible?) 代码如下所示:

    mParentView = new FrameLayout(mContext);mWM.addView(mParentView, params);mParentView.addView(mRootView);Animation animationUp = AnimationUtils.loadAnimation(mContext, R.anim.grow_from_bottom);mRootView.startAnimation(animationUp);

借助于ViewGroup(定义的mParentView),使用动画效果,小技巧很不错。

#参考

  1. QuickAction
  2. WindowManager with Animation (is it possible?)
  3. 官方文档

转载于:https://my.oschina.net/feiyangxiaomi/blog/511337

android的WindowManager.addView弹窗添加相关推荐

  1. Android开发学习之WindowManager实现弹窗

    背景 我们知道PopupWindow可以实现弹窗,但是如果要实现系统弹窗(即悬浮在所有view.dialog之上),需要调用通过反射PopupWindow类的私有方法setWindowLayoutTy ...

  2. Android之Window和弹窗问题

    目录介绍 10.0.0.1 Window是什么?如何通过WindowManager添加Window(代码实现)?WindowManager的主要功能是什么? 10.0.0.2 Window概念解析?W ...

  3. android分析windowManager、window、viewGroup之间关系

    本文将主要介绍addview方法,在windowManager.window.viewGroup中的实现原理.首先将介绍这些类结构关系,然后分析其内在联系,介绍实现原理,最后介绍重要的一个参数wind ...

  4. Android系统服务-WindowManager

    WindowManager是Android中一个重要的服务 (Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的各个 ...

  5. android cpu 悬浮窗口,Android 使用 WindowManager 实现悬浮窗监控 cpu 温度

    前文概要 连续四篇介绍了车载设置,主要都是和源码相关,还未看过的,可以参考借鉴学习一下源码知识.车载设置–按键提示音 本文开始进入下一个篇章,主要是和 camera 相关,例如倒车,TV ,360 全 ...

  6. Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

    7.1.1系统版本,我发现问题很多,比如 有个接口字段用了base64,但是我添加包的时候用的 java.util.base64 结果会崩溃报错,网上搜索后要用 android.util.base64 ...

  7. Android解析WindowManager(二)Window的属性

    相关文章 Android系统启动系列 Android深入四大组件系列 Android解析WindowManager系列 前言 在上一篇文章我们学习了WindowManager体系,了解了Window和 ...

  8. android view可视区域,Android使用WindowManager构造悬浮view

    一般在android显示一个View都是通过Activity的setContentView设置的,但是还有一种方法,可以直接使用WindowManager在整个应用的最上层绘制我们需要显示的view, ...

  9. Android 4.1.2系统添加重启功能

    对于Android的的手机或者平板长期使用,感觉会出现慢的情况,所以偶尔还是需要重启一下,而长按电源键弹出的菜单又没有重启选项,所以特在此记录自己添加这个功能的过程. 首先关机的那个弹出菜单是在fra ...

最新文章

  1. This graphics driver could not find compatible graphics hardware 解决
  2. python面试设计模式问题_聊聊 Python 面试最常被问到的几种设计模式(下)
  3. 资源:网页翻译API(文档)
  4. python3生成器_Python3.7之生成器
  5. Linux监控命令之==sar
  6. C#实现动态桌面背景图片切换(续)
  7. PayPal支付功能实现
  8. MATLAB三维图像与三重积分
  9. 低版本MAC如何升级系统
  10. Codeforces Round #657 (Div. 2) B. Dubious Cyrpto(思维,数学)
  11. Android Navigation与BottomNavigationView实现底部导航栏
  12. Python Selenium3.141+Win7(64位)+IEDriverServer(32位版本)+调用IE11卡死的解决
  13. gazebo入门教程(二)建立简单模型
  14. 【Vue3.0 + Element-plus】el-tree树状结构节点前箭头样式修改
  15. 安卓设置keychain_共享keychain数据
  16. 云服务器1和1g装什么系统好,1核1g的云服务器装什么系统好
  17. 〖Python APP 自动化测试实战篇⑥〗- 实战 - appium 定位手机元素之常用的元素定位方法
  18. 下列选项中 不能作为C语言标识符的是,2017计算机二级考试C语言复习题及答案...
  19. 【产品升级】愚人节不愚人,效率源手机取证产品SPF9139升级来袭!
  20. Python之财富自由——天天基金数据爬取并导入excel(详细信息爬取)

热门文章

  1. synchronized与Lock的区别与使用
  2. Citrix运行检测出错
  3. 关于supervisor 挂载woker和worker linke worker 的同样的结束等待
  4. Ubuntu修改IP地址和MAC地址
  5. 利用Mircosoft URLRewriter.dll实现asp.net页面伪静态
  6. 在R中调用Java代码
  7. foreach遍历进阶_“枚举器“/GetEnumerator()方法
  8. 成都郫县php开发学校_成都各区九年制学校、十二年制学校汇总
  9. 计算机运算器实验原理,计算机组成原理运算器实验—算术逻辑运算实验
  10. css面试基础知识,CSS知识点与面试题解析