如何手动聚焦特定视图?

时间:2012-03-28 23:14:17

标签: android android-layout android-widget

我正在尝试为只能使用d-pad遍历的启动器应用创建一个界面。我的布局是分层的,每个顶级项目都有一个选项列表。要导航到第二个列表,用户可以按该项目,也可以按向右键。

问题是,由于Android根据位置确定要聚焦的正确视图的方式,光标会跳转到不正确的项目(直接在光标旁边)。参见下面的图1;如果用户按下右键,将突出显示开发工具而不是API演示。

回到左边同样如此。在图2中,当用户按下右键时,将选择音乐而不是应用程序。

example of layout

到目前为止,我已尝试以下方法手动选择正确的视图:

appListView.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus) {
            ((ListView) v).getChildAt(0).requestFocus();
        } else {
            findViewById(R.id.apps_button).requestFocus();
        }
    }
});

这失败了(我假设)因为dpad动作已经触发了requestFocus,并且我已经验证我正在获得正确的子视图,子视图是可聚焦的,并且requestFocus()返回false; < / p>

如何使这项工作符合预期呢?在此先感谢:)

编辑1: 我还尝试将应用程序按钮NextFocusRightId设置为列表视图的第一项(由列表适配器@位置0以编程方式设置);什么都没有。

编辑2: NextFocus___Id也正在处理这些按钮,因为视频的焦点是设置,它工作正常......

2 个答案:

答案 0 :(得分:2)

我终于明白了!

手动聚焦列表项最好通过ListView本身完成。通过扩展ListView类并进行以下更改,它可以干净地向右移动:

@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
    if(gainFocus) {
        setSelection(0);
    } else {
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
    }
}

并在左边只设置listview的NextFocusLeft(而不是项目):

appListView.setNextFocusLeftId(R.id.apps_button);

答案 1 :(得分:0)

也许如果你实现了setOnKeyListener个视图并让它return true;来显示关键点击已被处理,那么它就不会触发两个requestFocus,你的将会正常工作。此外,实现此功能可能会阻止调用onFocusChangeListener,因此您可能必须自己在onKeyListener处理整个requestFocus,但这正是您想要的(我相信)

编辑:

怎么样:

view.setOnKeyListener(new View.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KEYCODE_DPAD_RIGHT:
                 ((ListView) v).getChildAt(0).requestFocus();
                 return true;
             case KEYCODE_DPAD_LEFT:
                 findViewById(R.id.apps_button).requestFocus();
                 return true;
             default:
                 return false;
         }
    }
});

这样,只有左侧或右侧dpad才会使用该事件。

相关问题