GoogleTv LeftNavBar焦点

时间:2012-07-19 05:14:25

标签: android-actionbar google-tv

我正在开发谷歌电视的应用程序,我必须在我的应用程序中使用left navigation bar。我下载了谷歌电视示例,并正在使用leftnavbar,以使其按照我的要求工作。我希望它表现得像一个电视和电视电影或谷歌电视的youtube应用程序。当焦点通过LEFT D-Pad键移动到其标签时它应该展开,当我使用RIGHT D-Pad键从焦点移动焦点时它会折叠。

我不知道是否有任何属性可以帮助我实现此功能。

所以我试着通过注册setOnFocusChangeListener监听器并在其中调用flipOption(LeftNavBar.DISPLAY_AUTO_EXPAND)函数,以强制它按照我想要的方式运行:

  private LeftNavBar getLeftNavBar() {
    if (mLeftNavBar == null) {
       -------
       -------
        mLeftNavBar.setOnFocusChangeListener(new View.OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                flipOption(LeftNavBar.DISPLAY_AUTO_EXPAND);
            }
        });


    }
    return mLeftNavBar;
}

现在,当leftNavBar中没有任何内容时,上面的代码工作正常。它显示/隐藏在接收/失去焦点时。但是当我在其中添加一些标签时,它不起作用。

任何想法如何实现它?

2 个答案:

答案 0 :(得分:2)

googletv-android-samples同时包含LeftNavBar代码和LeftNavBarDemo。如果您使用LeftNavBarDemo,您可以查看完成所查找行为所需的设置。

它只是设置正确的选项 - 你真的不需要flipOption onFocusChange - 如果你设置正确的初始选项,它将自动扩展和收缩。我会给你具体细节,但每个应用程序都不同。

答案 1 :(得分:0)

我猜测GTV团队已经在GoogleTV操作系统的视图层次结构中添加了一些特殊的调整因素,因为当LeftNavBar的任何一个孩子获得焦点时,下面会以某种方式调用这个神奇的方法。

protected void onDescendantFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (has(mDisplayOptions, LeftNavBar.DISPLAY_AUTO_EXPAND)) {
            setExpanded(hasFocus);
        }
    }

我无法看到如何使用其他方法模仿这个,所以我实现了下面的黑客攻击。

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();
    }