您的位置:首页 > 移动开发 > Android开发

Android  Windows悬浮窗

2015-11-03 23:40 525 查看
最近在工作中 正好在做悬浮窗的相关功能, 所以正好记录以下:

在Android中 有一种View 是覆盖在所有的Activity fragment上显示的,
那就是Window 就是我们经常看到个中app 的悬浮窗.

其实想再Window上显示View 很简单的:
1. 获取 WindowsManager
2. 初始化View 以及 相关的 WindowManager.LayoutParams()
3. 把View 添加到Window上
mWindowManager.addView(View, ViewParams);
mWindowManager.removeView(View);

需要注意的是, WindowManager.LayoutParams()
这里的配置项有点多
可以参考下下面这片文章上的一些讲解:
/article/9572710.html
下面给出一个 简单的配置:
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
layoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
layoutParams.format = PixelFormat.TRANSPARENT;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP;
layoutParams.flags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;

// 让键盘自适应 需要加入以下内容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
layoutParams.systemUiVisibility =
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
}


对了上面的代码有提到一点就是 键盘自适应的问题,
在Window上让键盘自适应 有一个问题, 就是 他会把整个Window 都往上移动,
在左锁屏这类的app时, 碰到输入框需要注意.
还有一个就是 键盘与 EditText 自适应的问题,
经过测试发现在 4.4 以上的手机 必须 设置 layoutParams.systemUiVisibility =View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
这样键盘弹出来时, EditText 也会自动上移

下面在说一说关于 那种可以在Window上可以移动的 那种 小悬浮窗 是如何实现的,
WindowParams = new WindowManager.LayoutParams();
int mMargin = mMarginLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getContext().getResources().getDisplayMetrics());
mMarginTop = mStatusBarHeight + mMargin;
mMarginRight = mScreenWidth - mBubbleEdgeSizeWidth - mMargin;
mMarginBottom = mScreenHeight - mBubbleEdgeSizeHeight - mMargin;

mWindowParams.x = mMarginRight;
mWindowParams.y = mMarginBottom;

mWindowParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mWindowParams.format = PixelFormat.RGBA_8888;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
mWindowParams.width = mBubbleEdgeSizeWidth;
mWindowParams.height = mBubbleEdgeSizeHeight;

上面就是一个小悬浮窗的基本 layoutParams
需要注意的是, mWindowParams.x, mWindowParams.y 还有mWindowParams.width,mWindowParams.height
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
这样就可以 将不点在 小悬浮窗 事件透过去, 本层Window不处理

mWindowParams.width,mWindowParams.height 给的都是 小悬浮球的view 的大小
mWindowParams.x, mWindowParams.y 表示这个小悬浮球view 在window 上的位置

我在移动小悬浮球View 的时候 监听到 onTouch方法, 然后获取event.getRawX(),event.getRawY() 获取在屏幕上的出门的位置, 然后经过一些简单计算,
最后吧值赋给 mWindowParams.x, mWindowParams.y, 如下
mWindowParams.x = x;
mWindowParams.y = y;

LogUtil.d(TAG, "x = " + x + ", y = " + y);
if (mWindowManager != null && isAttachedToWindow()) {
mWindowManager.updateViewLayout(this, mWindowParams);
}


这样就基本实现了VIew 的简单移动

下面说一说如果知识向在Window上显示而不获取任何点击事件:
可以使用下面设置:
layoutParams.flags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;


更多的设置项 还是需要 熟悉 相关文档:
/article/9572710.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: