想必大家都遇到过手势和焦点的问题 对于安卓初学者或者初次入职的开发人员或许是比较难的话题。
项目举例 如下图
需求:
图片是放在viewpager里面 实现轮播效果, 用户也可以左右滑动图片, 标题栏左右是个按钮 左边是更多 右边菜单 。
如果手指不在图片上,我们滑动屏幕默认是下方四个tab切换,到达最后一个(房子)弹出右边菜单,滑到第一个(五角星)弹出左边的侧滑菜单。
当手指处在图片时,我们滑动屏幕则需要是图片切换。
上图采用两个ViewPager+slidingmenu+ Fragment实现。广告Baner,也就是我们的ImageView所处的小的ViewPager,需要实现左右切换,整个首页的第一个Fragmen处在大的ViewPager中,那么这时候就会出现焦点混乱问题。
很多初次使以上两功能的人多会遇到这种问题 :比如我手在滑动图片上的时候 居然侧滑菜单出来了 而我们的想法是滑动查看图片 那么怎么做呢
先区分View和SlidingMenu:
我们给viewpager设置滑动监听OnPageChangeListener 我们可以自定义去实现此监听 关键代码如下
@Override public void onPageSelected(int position) { int lastPostion =adapter.getCount() - 1; if (position == 0) { ((SlidingFragmentActivity) activity). getSlidingMenu().setMode(SlidingMenu.LEFT); // 第一个。SlidingMenu仅有左边有效 ((SlidingFragmentActivity) getActivity()). getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); ; } else if (position == lastPostion) { /* ((SlidingFragmentActivity) activity). getSlidingMenu().setMode(SlidingMenu.RIGHT); // 最后一个。SlidingMenu仅有右边有效 */ ((SlidingFragmentActivity) activity). getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); } else { ((SlidingFragmentActivity) activity). getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);// 中间,SlidingMenu无效 只有边沿有效 } }
此方法就可以屏蔽slidingmenu抢焦点问题 现在就可以去试试了 搞定
区分大ViewPager和小ViewPager :
为了便于我们区分,给外层的ViewPager称之为FragmentVP, 小的ViewPager命名为ImageVP,如果对安卓时间不熟悉的请移步可以参考焦点事件文章 安卓Tv开发(一)焦点控制(触控事件),
那么抛开技术问题,我们首先想到:
1 当ImageVP可见,也就是滑到第一个Tab所指的Fragment时,我们需要获取图片的所在矩形范围。
2 当手指触摸范围在我们的矩形范围时,需要获得焦点,也就是主动要求焦点(requstFroce.
3 当手指触摸的位置不在图片的范围的,我们需要让FragmentVP获得焦点。
以上也只是初学者的理解,但是当我们真的代码这么去做的时候,发现上面方式无效,随之蛋疼的无法在蛋疼,于是楼主加了三天半还没搞定,最后阅读了事件源码,才发现原来罪魁祸首在于它。
理解了事件源码的朋友都知道,当我们手指按在图片上时,首先由最外层所处的Activity收到事件,以此分发传递到我们的图片上,那么这个时间在哪里被拦截了,也就是所消费了,我不断追踪断点,最后发现,原来再我们的最外层的FragmentVP所不在传递,由他的执行onTouchEvent()消费了。
1 )重写FragmentVP 的onInterceptTouch()不让拦截事件,具体我们返回fasle即可,
PS: 这里需要你做下if判断,所处手指在imageView上我们不拦截,反之拦截
2)当然到这里还不行,因为此时还会触发FragmentVP 的dispathTouchEvent(),还需要重载此方法,返回true,意思就是继续往下传递,具体事件原理请阅读上面的文章,这里只给出解决方法,
Ps:这里需要你做下if判断,所处手指在imageView上我们传递,反之不传递
3 我们还要去重写ImageVP的onTouchEvent()方法,让他消费此事件,具体我们返回true即可,
有了思路写起来很易,代码就不在贴了,谢谢阅读。