您的位置:首页 > 移动开发 > Android开发

android focus 查找

2015-08-02 17:20 841 查看
在焦点模式下,当我们按下方向键的时候,android系统就会调用当前焦点控件的focusSerach方法,找到下一个焦点的控件,并把焦点赋给它。

一般情况下,Android系统查找的焦点,是以中心点为依据(没有看源码,从平常操作的感觉是这样),按指定的方向,找到距离当前控件中心点最近的下一个控件。

通常这正是我们需要的焦点顺序。但是,凡是总有例外。有时候我们想要的焦点顺序和系统查找的顺序不一致,这时候,有什么办法吗?

以下介绍两种方法:

一、当我们明确知道,下一个获取焦点的控件时,可以调用setNextFocusUpId()的方法(当然,还有对应的setNextFocusDownId,setNextFocusLeftId,setNextFocusRightId等方法)。系统查找下一个焦点的时候,就会返回我们设置id的那个控件。

二、当我们无法知道下一个控件的ID的时候,可以重写focusrSearch方法。

这种方法就比较复杂了,需要根据实际情况来改写,当然,需要了解focusSearch的原理,才能改写。

ok,开始分析focusSearch的原理。

来看一下focusSearch的时序图:



分为以下步骤:

1、按下方向键的时候,系统就会调用到当前焦点的searchFocus(int direction)方法。源码如下:

public View focusSearch(@FocusRealDirection int direction) {
if (mParent != null) {
return mParent.focusSearch(this, direction);
} else {
return null;
}
}


2、从上面代码第三句代码中可以看到,它会调用parent(ViewGroup)的focusSearch(View focused,int ditection)的方法。源码如下:

public View focusSearch(View focused, int direction) {
if (isRootNamespace()) {
// root namespace means we should consider ourselves the top of the
// tree for focus searching; otherwise we could be focus searching
// into other tabs.  see LocalActivityManager and TabHost for more info
return FocusFinder.getInstance().findNextFocus(this, focused, direction);
} else if (mParent != null) {
return mParent.focusSearch(focused, direction);
}
return null;
}


3,先看上面代码第8行,如果当前节点还不是根节点的话,就调用父节点的focusSearch继续查找,直到根节点为止(第6行)。在根节点调用

findNextFocus(ViewGroup root, View focused, int direction)的方法,并把根节点赋值给它。

public final View findNextFocus(ViewGroup root, View focused, int direction) {
return findNextFocus(root, focused, null, direction);
}
private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction) {
View next = null;
if (focused != null) {
next = findNextUserSpecifiedFocus(root, focused, direction);
}
if (next != null) {
return next;
}
ArrayList<View> focusables = mTempList;
try {
focusables.clear();
root.addFocusables(focusables, direction);
if (!focusables.isEmpty()) {
next = findNextFocus(root, focused, focusedRect, direction, focusables);
}
} finally {
focusables.clear();
}
return next;
}
第二段代码的第4行,就是先查找用户设置的nextFocus。即第一种方法设置的setNextFocusUpId等。

接下来就是按照算法查找下一个焦点,现在还没有必要完全了解。

从上面的分析中,有两个重点需要注意:

1、focusSearch只是查找下一个获取焦点的控件,但改控件还未获取焦点(需要调用requestFocus后才能获取焦点)。

所以,可以充值focusSearch的方法,来选择自己需要的下一个焦点。

2、注意看这个方法:FocusFinder.getInstance().findNextFocus(ViewGroup root, View focused, int direction).它的第一个参数是ViewGruop,所以,如果你需要限定在某个ViewGruop中查找控件,就可以在focusSeach中调用这个方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: