Weex使用随记(二):当mask遇上虚拟导航栏

首先我们先看这样一个bug


可以看出mask的布局不会随着虚拟导航功能的显示和隐藏进行重新布局,就出现了这个可有可无的bug。

通过查看mask的源码可以看到mask的通过PopupWindow实现的,


这样会有2个难以控制的因素。

1,PopupWindow的布局是不会随着虚拟导航的显示隐藏而重新布局。

2,PopupWindow设置setBackgroundDrawable后点击返回键就会关闭,而且无法拦截。

从PopupWindow源码可以看出,所以这里会有一个致命的问题,无法通过mask进行阻塞用户的下一步操作。

所以我认为通过PopupWindow来实现mask是很不合理的。

为了解决上面的问题理论上是可以通过dialog和模仿PopupWindow获取WindowManager进行自定义自己的PopupWindow。

通过dialog实现的时候出现了一些很诡异的问题,所以我采用了模仿PopupWindow来实现的,目前还没有发现什么问题。当然今天的重点不是这两种方案,而是我前不久突发奇想的第三种比较另类的方案。经过一下午的调整终于算是搞定了。

核心代码:https://github.com/ws616628604/Weex/blob/master/playground/app/src/main/java/com/alibaba/weex/yzh/MyMask.java

原理很简单,我把mask加载到了contentView上了。


首先我给activity扩展了一个监听返回键的方法,这样我们可以把用户的返回操作交给前段来处理,解决了第二个问题。



然后给contentView添加一个LayoutChangeListener,监听虚拟导航栏的显示隐藏导致的高度改变,然后调用重新设置高度的方法把最新的高度设置进去。这样第一个问题就轻松解决了。

最后再在初始化weex 的时候把自己的mask替换上去就行了


然后来一个修改后的效果图



当然这种方案其实还是有一个小小的bug的,Activity的dispatchKeyEvent方法的调用时机是晚于获取焦点的view的dispatchKeyEventPreIme方法的,不过这种问题是可以忽略不计的。


补充:

其实我们也可以参考Android-PickerView拦截返回键的解决方案,最后千万不要忘了调用

rootView.requestFocus();

rootView.requestFocus();

rootView.requestFocus();

重要的事情说3遍,本来我就想采用这种方案的就是没有调用这个方法导致没有测试成功,最终改在activity添加接口,后来忽然想到Android-PickerView,经过多次对比才发现。尴尬


最后再附上测试地址:http://dotwe.org/vue/cc7a28d543d3c08517030c852677c719

你可能感兴趣的:(Weex使用随记(二):当mask遇上虚拟导航栏)