Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use D-pad navigate switch between listview's row and it's decendants (Google-TV support)

I have a listview which has an imageview inside each list item, when user click on that imageview, it will pop-up a menu.

It works very well on a normal android device with a touch screen.

But now I want to support google-tv, which app should be control by D-pad.

When I use D-pad to navigate through listview, only the entire row can be focus, I can't get the imageview inside listview be focus.

I try to add android:focusable="true" to imageview, but it cause the entire listview can't receive onItemClick event.

Does anyone know how to move the focus between listview rows and item inside listview using d-pad also keeps listview and imageview clickable?

Thanks a lot!

like image 783
henry74918 Avatar asked Jan 18 '13 04:01

henry74918


2 Answers

You have to set the following for your ListView:

listView.setItemsCanFocus(true);

With that focusable views inside of your listItems won't be ignored.

like image 76
Matthias Avatar answered Oct 22 '22 01:10

Matthias


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);
}
like image 38
henry74918 Avatar answered Oct 22 '22 03:10

henry74918