Как вручную сфокусировать конкретный вид? - PullRequest
2 голосов
/ 29 марта 2012

Я пытаюсь создать интерфейс для приложения запуска, которое можно просмотреть, используя только d-pad.Мой макет иерархический, каждый элемент верхнего уровня имеет список параметров.Чтобы перейти ко второму списку, пользователь сможет нажать элемент или нажать вправо.

Проблема в том, что из-за способа, которым Android определяет правильный вид для фокусировки в зависимости от местоположения, курсор переходит к неправильному элементу (который всегда находится непосредственно рядом с курсором).Обратитесь к рисунку 1 ниже;если бы пользователь нажал вправо, вместо демонстраций API были бы выделены инструменты Dev.

То же самое относится и к возврату влево.На рисунке 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;

Что я могу сделать, чтобы сделать эту работу, как ожидалось?Заранее спасибо:)

РЕДАКТИРОВАТЬ 1:
Я также только что попытался установить кнопки приложения NextFocusRightId на первый элемент представления списка (который программно устанавливается адаптером списка @ position 0);ничего.

РЕДАКТИРОВАТЬ 2: NextFocus___Id также работает на этих кнопках, так как видео вверх фокусируется на Настройки, который работает нормально ...

Ответы [ 2 ]

2 голосов
/ 10 апреля 2012

Я наконец понял это!

Ручную фокусировку элементов списка лучше всего выполнять через сам ListView.Он работает чисто, двигаясь вправо, расширяя класс ListView со следующим изменением:

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

и влево, просто устанавливая NextFocusLeft списка (а не элементов) следующим образом:

appListView.setNextFocusLeftId(R.id.apps_button);
0 голосов
/ 10 апреля 2012

Возможно, если вы реализуете setOnKeyListener представлений и имеете его return true;, чтобы показать, что нажатие клавиши было обработано, тогда не будет запущено два requestFocus, и ваш будет работать правильно. Кроме того, реализация этого может помешать вызову onFocusChangeListener, поэтому вам, возможно, придется обрабатывать весь requestFocus самостоятельно в onKeyListener, но это именно то, что вы хотите (я считаю)

EDIT:

А как же:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...