Focus事件处理

首先我们来看一下View是怎么获得Focus.Focus是如何在View间跳转的呢?

 

查阅源码可以看到对KeyEvent的处理是在ViewRootImpl.processKeyEvent()


 

mView.dispatchKeyEvent(event)对事件进行了分发,并且如果返回true将结束事件处理,返回FINISH_HANDLED.

 

我们知道view对事件的处理都是从dispatchKeyEvent分发开始的,看一下dispatchKeyEvent的源码是怎样的呢?


如果View设置了OnKeyListener, 并且ViewENABLED,满足前面两个条件后,就会进行第三个条件判断,即回调onKey方法对事件进行处理。这里就会有个疑问了,如果onKey也返回true,dispatchKeyEvent就直接返回ture, 整个事件处理是不是就结束了?

这里可以进行一下测试:


对一个view设置OnKeyListener,并在onKey方法里,如果是KEYCODE_DPAD_DOWN,直接返回true.

可以看到,当FocusTextView,点击KEYCODE_DPAD_UPFocus可以跳到Button,但是点击KEYCODE_DPAD_DOWN Focus就不会跳到BUTTON2.(如果在onKey里返回trueonClick事件也不会触发。这里可以认为是事件已经被消化,不会再往下分发,)

 

 

回到我们的focus问题上,如果dispatchKeyEvent返回true,focus不会跳转,说明focus的处理还在dispatchKeyEvent之后,这里回到ViewRootImpl.processKeyEvent()里。


这里根据KEYCODE设定viewfocus方向。


使用上面FocusTextViewBUTTON的例子,这里mView就是TextView,这时候TextView是有focus的,所以这里的focused也是TextViewfocused.focusSearch(direction)就是通过已经获取了focusview和下一次focus的方向找到下一次要focusview。说得好绕,还是直接看代码吧ViewRootImpl.focusSearch()



真正处理的方法在FocusFinder.findNextFocus(), 这里要注意mViewTextViewparent,focusedTextView.


findNextUserSpecifiedFocus先找用户自定义的下一个focusview,这里我们没有定义,不需要考虑。

root.addFocusables将所有可以获取focusview添加到focusables里面

ViewGroup.addFocusables()



像遍历树一样遍历root的所有子view和孙view,然后调用View.addFocusableisFocusableview添加到focusables.

把所有focusableview找出来后,就可以通过算法找到下一个要focusview了。

next = findNextFocus(root, focused,focusedRect, direction, focusables);(看不懂算法是如何实现1))

 

 

 

 

 

 

 

现在来看一下第二个问题:ViewGroup和子类View哪一个获取focus.

ViewGroup有个属性android:descendantFocusability

属性的值有3种:

"beforeDescendants" ViewGroup会优先其子类控件而获取到焦点 – ViewGroup获得focus(ViewGroup获得focus后,在按其他键,focus也跳不到去子类)

"afterDescendants":只有当其子类不需要获取焦点时ViewGroup才获取焦点子类先获得focus(如果所有子类focusable = false, 父类获取focus)

"blocksDescendants"ViewGroup覆盖子类直接获取焦点 --ViewGroup获得focus

 

这个是怎么实现的呢?其实就在ViewGroup.addFocusables


FOCUS_BLOCK_DESCENDANTS

只加自己到focusable,不加孩子

FOCUS_AFTER_DESCENDANTS:

只加孩子不加自己到focusable

FOCUS_BEFORE_DESCENDANTS:

先加孩子,再加自己到focusable

 

 

 

3. focusableInTouchMode触摸的时候会获取focus

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值