进击的小羊

实现一个复杂悬浮框

且看这次的背景,产品需要实现这样一个dialog

这里写图片描述

考虑到dialog中界面的复杂,使用dialog有点难以控制生命周期,所以我们想使用Activity来实现,但是实现了之后,发现了坑爹的事情,在按了home键之后在service中启动activity会有5秒钟的延时,具体请看这在产品上是不能忍受的,所以又回到了dialog上。

先实现悬浮窗小圆球,这个不难,但是很快遇到了第一个坑,在小米和魅族上,悬浮框的权限是被默认静止的,但是引导用户打开的成本太高,那怎么绕过权限申请尼?很幸运有人已经填平了这个坑

1
2
3
4
5
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mFloatParams.type = LayoutParams.TYPE_TOAST;
} else {
mFloatParams.type = LayoutParams.TYPE_PHONE;
}

接着实现dialog页面,发现dialog的宽高显示不正常,其实代码是没有问题的

1
2
3
4
5
6
7
8
9
10
11
12
13
public void setWindowsSize() {
Window window = getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
DisplayMetrics dm = new DisplayMetrics();
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
lp.width = (int) (screenWidth * 0.88);
width = lp.width;
lp.height = (int) (screenHeight * 0.79);
window.setAttributes(lp);

}

那为什么dialog的显示不正常尼..后来发现必须在dialog show()之后再设置setWindowsSize()才可以,具体原因未知,以后再细究.

小圆圈悬浮窗和dialog都实现之后,就开始写轮询的逻辑了,我比较喜欢使用alarmManager,因为他是独立的RTC模块,不会因为应用休眠就停止运行,这时候遇到了第三个坑,就是在小米手机上,dialog还显示在前端,但是轮询接口却断开了网络的连接,因为之前吃过神隐模式的亏,所以我第一时间把锅定位在了神隐模式上,据我所知,神隐模式会在应用进入后台之后断开应用的网络,但是我这个dialog还显示在界面上,很明显因为我在dialog上设置了 window.setType(WindowManager.LayoutParams.TYPE_TOAST),所以导致系统判断应用已经处于后台,虽然界面上有个这么复杂的toast,那么解决方案也有了,要么将Dialog设置为TYPE_SYSTEM_ALERT,要么对照上一篇博客来处理神隐模式

整个工程就是踩了这三个坑的过程中渡过,坑不打,但是也消耗了不少时间,Android开发至今,已经很少遇到踩不平的坑,更是很难遇到前人踩不平,我也踩不平的坑了,写这篇博客,主要是为了以后自己查找方便,如果能帮到踩坑中你,那也就功德圆满了。