I got my Listview work with D-pad which can switch focus inside a list item.
This is how I solve it.
First, let your list view is item focusable.
NOTE: If you trying to set ItemsCanFocus to false later in your code, your will find your list item can't get focus anymore even if your set back to true again, so don't do that.
mDpadListView.setItemsCanFocus(true);
Then you need a field to keep tracking which list item is current selected.
Here I put the ViewHolder in the listItem's tag in Adapter.
mDpadListView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if (view.getTag() != null) {
DpadListAdapter.ViewHolder holder = (ViewHolder) view.getTag();
if (holder.shortCut != null && holder.shortCut.isShown()) {
currentSelectView = view;
} else {
currentSelectView = null;
}
} else {
currentSelectView = null;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Third, override onKeyDown() in Activity Method to control up, down, left, right key for D-pad.
When user press right button on D-pad, I let the listview to clearFoucs() and let the ImageView inside to obtain focus.
When user press up, down or left, the ImageView in list item will clear it's focus and the listView obtain focus again.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (currentSelectView != null) {
DpadListAdapter.ViewHolder holder =
(ViewHolder) currentSelectView.getTag();
mDpadListView.clearFocus();
holder.shortCut.setFocusable(true);
holder.shortCut.requestFocus();
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
if (currentSelectView != null) {
DpadListAdapter.ViewHolder holder =
(ViewHolder) currentSelectView.getTag();
if (holder.shortCut.hasFocus()) {
holder.shortCut.clearFocus();
holder.shortCut.setFocusable(false);
mDpadView.requestFocus();
return true;
}
}
break;
default:
break;
}
return super.onKeyDown(keyCode, event);
}