android提供了一些焦点相关的属性,在现有的框架层下通过设置View的属性来获得焦点:
- android:focusable:设置一个控件能否获得焦点
- android:nextFocusDown:(当按下键时)下一个获得焦点的控件
- android:nextFocusDown:(当按下键时)下一个获得焦点的控件
- android:nextFocusLeft:(当按下键时)下一个获得焦点的控件
- android:nextFocusRight:(当按下键时)下一个获得焦点的控
**注意:**如果按下某个方向键时,想让焦点停留在自身,可以使用
android:nextFocusRight:"@null"
或者android:nextFocusRight:"@id/自身id"
這只有在對view是有效的,對viewgroup等類是無效的 原因在於
private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
// check for user specified next focus
View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
View cycleCheck = userSetNextFocus;
boolean cycleStep = true; // we want the first toggle to yield false
while (userSetNextFocus != null) {
if (userSetNextFocus.isFocusable()
&& userSetNextFocus.getVisibility() == View.VISIBLE
&& (!userSetNextFocus.isInTouchMode()
|| userSetNextFocus.isFocusableInTouchMode())) {
return userSetNextFocus;
}
userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
if (cycleStep = !cycleStep) {
cycleCheck = cycleCheck.findUserSetNextFocus(root, direction);
if (cycleCheck == userSetNextFocus) {
// found a cycle, user-specified focus forms a loop and none of the views
// are currently focusable.
break;
}
}
}
return null;
} 他在搜尋usersetnextfocus是用該focus view去找的 viewgroup自然對於該function就無作用。
private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
// check for user specified next focus
View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
View cycleCheck = userSetNextFocus;
boolean cycleStep = true; // we want the first toggle to yield false
while (userSetNextFocus != null) {
if (userSetNextFocus.isFocusable()
&& userSetNextFocus.getVisibility() == View.VISIBLE
&& (!userSetNextFocus.isInTouchMode()
|| userSetNextFocus.isFocusableInTouchMode())) {
return userSetNextFocus;
}
userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
if (cycleStep = !cycleStep) {
cycleCheck = cycleCheck.findUserSetNextFocus(root, direction);
if (cycleCheck == userSetNextFocus) {
// found a cycle, user-specified focus forms a loop and none of the views
// are currently focusable.
break;
}
}
}
return null;
} 他在搜尋usersetnextfocus是用該focus view去找的 viewgroup自然對於該function就無作用。
一般來說focusSearch是focus主要的來源,如果都不override他就是一路找到decorView?或許吧,使用FocusSearchInstance來找,那個Util會把子Views focusable的全找出來作排序用rect的方式去找最靠近的focus, 除非你有指定id. 原生的四大主件LinearLayout RelativeLayout ...全都沒有複寫這method. 只有Leanback library的元件才有,所以客製化的頁面UI幾乎全都要自己override這method來控制focus。至少我認為是這樣。
@Overridepublic View focusSearch(View focused, int direction) { View returnView = null; ViewParent trace = focused.getParent(); while (trace != null) { if (trace instanceof SlidingTabLayout) { returnView = FocusFinder.getInstance().findNextFocus((ViewGroup) trace, focused, direction); break; } else if (trace instanceof ViewPager) { returnView = FocusFinder.getInstance().findNextFocus((ViewGroup) trace, focused, direction); break; } trace = trace.getParent(); } if (trace instanceof SlidingTabLayout && direction == View.FOCUS_DOWN) { return pager; } if (trace instanceof ViewPager && direction == View.FOCUS_UP) { return tabs.getSelectedView(); } return returnView == null ? super.focusSearch(focused, direction) : returnView;}
以上是一些客製化的範例。
沒有留言:
張貼留言