在工作中遇到一个需求,需要在整个应用的上层悬浮显示控件,目标效果如下图:
WindowManager WindowManager=(WindowManager) applicationContext.getSystemService (Context.WINDOW_SERVICE); WindowManager。LayoutParams LayoutParams=new WindowManager.LayoutParams (); layoutParams。类型=WindowManager.LayoutParams.TYPE_TOAST; windowManager。addView(视图,layoutParams);
而系统在添加TYPE_TOAST类型控件时默认不需要权限,从而可以绕过悬浮窗权限。但是这种做法并不适配所有机型,比如我亲测过的小米(MIUI8)和安装7.1.1 Nexus机型上就会报错拒绝许可,需要申请权限,之前这种方式或许可行,但现在肯定不行。
放弃TYPE_TOAST方案,不能往窗口里添加视图,那只能乖乖的申请权限了吗?这时你可能想到往所有活动的固定位置添加视图、模拟“悬浮”效果,比如要实现文章开头的效果,只需要进入新活动时初始化旋转的角度,让其在视觉上连续就行了。
但是要考虑一个问题,在切换活动时旧活动的悬浮控件是要销毁的,新活动的悬浮控件是要生成的,也就是说在切换活动时这个悬浮控件是会短暂的消失一下,那把活动切换效果设置为淡入淡出可以吗,在视觉上是可以实现的,但是严格限制了活动的切换效果,不可行。那还有什么方法可以实现切换活动时控件在视觉上连续吗?如果你用过共享元素动画的话,便有答案了。
悬浮控件在哪里添加呢?可以在BaseActivity里,也可以应用程序为注册活动生命周期回调,下面通过后者实现,在应用程序中为每个活动添加悬浮控件:
公开课BaseApplication扩展应用程序{ @Override 公共空间> 目的意图=new意图(这个,Main2Activity.class); 视图视图=findViewById (R.id.floating_view_id); 如果(视图!=null) { ActivityOptionsCompat选项=ActivityOptionsCompat.makeSceneTransitionAnimation ( 视图,getString (R.string.transitionName)); ContextCompat。startActivity(意图,options.toBundle ()); 其他}{ startActivity(意图); } >之前这样就解决了切换活动时悬浮控件短暂消失一下这个问题,然后在添加悬浮控件时,初始化旋转角度就可以实现文章开头的效果了。但是这种方式存在很大的缺陷,首先就是它不兼容Andorid 5.0以下,看看4.4那百分之十几的小伙伴,嗯~缺陷很大,其次还有一个致命缺陷,不管把悬浮控件设为不可见的还是透明,只要已经添加了此控件,在切换时它都会先显示一下,这应该是共享元素动画本身的一个错误。
好~放弃共享元素方案,真的绕不过申请权限了吗& # 63;再考虑一下TYPE_TOAST方案,为什么它失效了呢& # 63;应该是系统对此类型的控件加了限制,对待TYPE_TOAST不再跳过检查权限步骤,而是像TYPE_PHONE之类一视同仁,那为什么我们的面包却可以跳过呢& # 63;面包不就是TYPE_TOAST类型的视图吗& # 63;不管如何,反正烤面包是不需要权限的,那就尝试从土司入手。好吧~,现在的关键词是自定义吐司。
查看吐司类源码,有一个方法眼前一亮:
/* * *设置视图来显示。 * @see # getView */公共空间setView(查看视图){ mNextView=视图; }浅谈Android应用内悬浮控件实践方案总结