浅谈Android应用内悬浮控件实践方案总结

  

在工作中遇到一个需求,需要在整个应用的上层悬浮显示控件,目标效果如下图:

  

浅谈Android应用内悬浮控件实践方案总结”> <br/>
  </p>
  <p>首先想到的是申请悬浮窗权限,好吧~打开搜索引擎,映入眼帘的并不是如何申请,而是“Android悬浮窗权限各机型各系统适配大全,Android绕过权限显示悬浮窗……”,为什么悬浮窗权限会有这么多坑呢?悬浮窗可以在桌面显示,被恶意软件用来偷偷弹广告怎么办?作为一个系统级别的特殊权限,这是它应有的高傲——</p>
  <p>正确引导用户打开悬浮窗权限才是标准做法,若这就是定论的话这篇文章也没必要写了,我们绕过悬浮窗权限直接去显示,大多数是为了优化用户体验,并不是恶意的。有时我们只想在自己的应用内实现悬浮窗,然而Andorid并没有提供这样的方法,也只好退而求其此的去使用系统级别的悬浮窗权限。</p>
  <p>好的,既然可以绕过权限申请,再重新定义一下需求:</p>
  <p>尽量绕过申请权限,实现在应用指定界面显示悬浮控件,控件的位置不需要改变<br/>
  </p>
  <p>怎么绕过悬浮窗权限呢?网上大多数通过WindowManager添加一个TYPE_TOAST类型的控件,如下:</p>
  
  <pre类=   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应用内悬浮控件实践方案总结