我正在尝试为只能使用d-pad遍历的启动器应用创建一个界面。我的布局是分层的,每个顶级项目都有一个选项列表。要导航到第二个列表,用户可以按该项目,也可以按向右键。
问题是,由于Android根据位置确定要聚焦的正确视图的方式,光标会跳转到不正确的项目(直接在光标旁边)。参见下面的图1;如果用户按下右键,将突出显示开发工具而不是API演示。
回到左边同样如此。在图2中,当用户按下右键时,将选择音乐而不是应用程序。
到目前为止,我已尝试以下方法手动选择正确的视图:
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也正在处理这些按钮,因为视频的焦点是设置,它工作正常......
答案 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才会使用该事件。