我猜 GTV 团队在 GoogleTV 操作系统中的 View Hierarchy 中添加了一些特殊的调味料,因为当 LeftNavBar 的任何子项获得焦点时,会以某种方式调用下面的这个神奇方法。
protected void onDescendantFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (has(mDisplayOptions, LeftNavBar.DISPLAY_AUTO_EXPAND)) {
setExpanded(hasFocus);
}
}
我看不出如何使用其他方法来模仿它,所以我实现了下面的 hack。
1) 在 LeftNavView.java 的 onFinishInflate() 末尾添加以下代码来检测底层列表视图何时获得焦点,以便您可以展开菜单。不幸的是,它并不像使用 hasFocus == false 那样简单地可靠地关闭菜单,因此请参阅第 2 步。
@Override
protected void onFinishInflate() {
//...
//existing code
//...
TabListView tabListView = (TabListView)mTabs.getView();
tabListView.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
setExpanded(true, true);
}
});
}
2) 在LeftNavView.java 的focusSearch(boolean hasFocus) 顶部添加以下内容以折叠菜单(如果LeftNavBar 已经有焦点并且DPAD 方向是正确的。
@Override
public View focusSearch(View focused, int direction) {
//if leftnav hasFocus but direction is right then collapse the nav menu
if (hasFocus() && direction == View.FOCUS_RIGHT) {
setExpanded(false, true);
}
//...
//existing code
//...
}
CAVEAT:使用这个 hack,您需要注意在加载时没有请求焦点的视图(调用 .requesFocus() 或在布局中实现 requestFocus/> 标签)。在这种情况下,您的视图将获得焦点,但菜单仍将展开,并且在某些情况下,您将无法使用 dpad 将焦点重新放在菜单上(取决于视图的布局)
如果您想将某些内容集中在新加载的片段中,那么您可以实现并调用下面的方法(在 onActivityCreated() 的末尾)作为解决方法。
//e.g. passing in KeyEvent.KEYCODE_DPAD_RIGHT
public static void simulateKey(final int KeyCode) {
new Thread() {
@Override
public void run() {
try {
Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyCode);
} catch (Exception e) {
Log.e(TAG, "Exception when sendKeyDownUpSync " + e.toString());
}
}
}.start();
}