2

我正在为谷歌电视开发应用程序,我必须left navigation bar在我的应用程序中使用。我下载了 google tv 示例并正在使用 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 中没有任何内容时,上面的代码可以正常工作。它在接收/失去焦点时显示/隐藏。但是当我在其中添加一些选项卡时它不起作用。

任何想法如何实现它?

4

2 回答 2

2

googletv -android-samples有 LeftNavBar 代码和 LeftNavBarDemo。如果您使用 LeftNavBarDemo,您可以查看需要哪些设置来完成您正在寻找的行为。

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

于 2012-07-19T18:38:05.767 回答
0

我猜 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();
    }
于 2013-10-03T15:11:59.793 回答