android的WindowManager.addView弹窗添加
2015-09-25 18:24
651 查看
touch here
android在WindowManager添加View
作者:feiyangxiaomi
[TOC]
#1. 事情的起因
项目的驱动,希望提供一个弹窗,这个弹窗的特点是:
非阻塞试弹窗,弹窗弹出的时候,点击弹窗外的屏幕区域,--不选PopupWindow(开源项目QuickAction不能用)
弹窗需要内部能够点击某一项并做出相应,--不选Toast
此时考虑在界面上加入一个View,通过WindowManager.addView方法去添加弹出图层,这里先贴出一个图,看一下这个效果是否是你的菜:
//截图
#2. 为什么选择WindowManager.addView
WindowManager用来在应用与window之间的管理接口,管理窗口顺序,消息等。对于windowManager来说一个系统只有一个,它是由系统底层实现的,用于负责调度当前显示那个窗口,消息处理我们获得一个windowManager的方式如下:
调用比较简单。
#3.代码实现
把这个弹窗叫做
##显示
其中初始化View,添加菜单项和设置点击菜单项的点击回调,参考QuickAction的代码,这里不再介绍。
#4.本文的目标点
##WindowManager和WindowManager.LayoutParams
添加的view不显示,引出WindowManager.LayoutParams用什么type?
属性WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,如何响应点击outside和back键盘?可以看下stackoverflow很有意思
属性WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY能不能用?
对于WindowManager.LayoutParams配置代码:
可以看到这里使用的
flag使用
|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|
参考网上实例的时候,建议不要采用系统图层,网上的好多实例都是采用:
###WindowManager.addView的动画效果
动画部分可以采用:
那怎么办?参考:WindowManager with Animation (is it possible?)
代码如下所示:
借助于ViewGroup(定义的mParentView),使用动画效果,小技巧很不错。
#参考
QuickAction
WindowManager with Animation (is it possible?)
官方文档
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
添加的view不显示,引出WindowManager.LayoutParams用什么type?
属性WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,如何响应点击outside和back键盘?可以看下stackoverflow很有意思
属性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),使用动画效果,小技巧很不错。
#参考
QuickAction
WindowManager with Animation (is it possible?)
官方文档
相关文章推荐
- android-support-v7 问题 解决
- android bitmap 平铺
- 深入Android 'M' Doze
- Android常用工具类
- Android 通过resource名称或者layout中定义的id name 去获取R.java中id,得到控件
- android中反射机制
- android异步任务详解 AsynTask
- Android之DiskLruCache(缓存工具)
- Android高效加载大图、多图解决方案,有效避免程序OOM
- android json解析(fastjson,Gson等)
- Android瀑布流照片墙实现,体验不规则排列的美感
- Android动画之translate(位移动画)
- android fastjson
- 【Android】多功能二维码实现思路,自动连接WI-FI
- Android应用是否可以只有一个Service或Broadcast Reciver,而没有Activity?
- 【Android】 从头搭建视频播放器(3)——手势检测 & 控制
- Android -- Properties使用
- android模拟器中关闭应用进程
- 查看
- [转]Android自定义控件系列五:自定义绚丽水波纹效果