Как использовать переключатель навигации D-pad между строкой listview и ее decendants (поддержка Google-TV)

У меня есть listview, который имеет imageview внутри каждого элемента списка, когда пользователь нажимает на этот imageview, он появится меню.

Он очень хорошо работает на обычном устройстве android с сенсорным экраном.

но теперь я хочу поддерживать google-tv, какое приложение должно управляться D-pad.

когда я использую D-pad для навигации по listview, только вся строка может быть фокусом, я не могу получить imageview внутри listview быть фокусом.

Я пытаюсь добавить android: focusable= "true" для imageview, но это приводит к тому, что весь listview не может получить событие onItemClick.

кто-нибудь знает, как переместить фокус между строками listview и элементом внутри listview с помощью d-pad также сохраняет ListView и imageview кликабельным?

Спасибо большое!

3 ответов


вы должны установить следующее Для своего ListView:

listView.setItemsCanFocus(true);

при этом фокусируемые представления внутри ваших listItems не будут игнорироваться.


я получил работу Listview с D-pad, которая может переключать фокус внутри элемента списка. Вот как я это решаю. Во-первых, пусть ваше представление списка является элементом focusable.

Примечание: Если вы пытаетесь установить ItemsCanFocus в false позже в коде, ваш элемент списка не сможет больше фокусироваться, даже если ваш набор снова будет true, поэтому не делайте этого.

mDpadListView.setItemsCanFocus(true);

затем вам нужно поле, чтобы отслеживать, какой элемент списка выбран текущим. Здесь я помещаю ViewHolder в список бирка в переходнике.

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) {
    }
});

В-третьих, переопределите onKeyDown () в методе Activity для управления вверх, вниз, влево, вправо для D-pad.

когда пользователь нажимает правую кнопку на D-pad, я позволяю listview clearFoucs() и позволяю ImageView внутри, чтобы получить фокус.

когда пользователь нажимает вверх, вниз или влево, элемент ImageView в списке очистит его фокус, и listView снова получит фокус.

@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);
}

вы можете использовать свойства для доступа к D-pad, как показано ниже в файле макета:

        android:nextFocusLeft="@+id/abc"
        android:nextFocusRight="@+id/xyz"
        android:nextFocusUp="@+id/pqr"
        android:nextFocusDown="@+id/mno"
        android:nextFocusForward="@+id/finish"

Это все свойства помогут вам получить доступ к D-pad в Google-TV.