Пользовательская обработка ориентации в ViewGroup

Скажем, у меня есть настраиваемая ViewGroup, которая является настраиваемой и имеет некоторые дочерние представления, которые также могут быть сфокусированы (пользовательское вертикальное меню для Android-приставки, которое должно реагировать на пульте дистанционного управления).

Мне нужно передать фокус некоторым дочерним представлениям, когда пользовательская группа ViewGroup получает фокус.

Я установил descendantFocusability в beforeDescendants и установил OnFocusChangeListener в пользовательскую ViewGroup, но OnFocusChangeListener.onFocusChanged() никогда не вызывается. Похоже, что beforeDescendants работает не так, как я ожидал. Фактически установка beforeDescendants работает так же, как установка afterDescendants. Фокус берется с помощью ближайшего дочернего вида, а пользовательская ViewGroup не имеет возможности решить, какой дочерний вид должен делать фокус.

Как я могу достичь желаемого поведения? Каковы наилучшие методы обработки фокусов в ViewGroup s?

Ответы

Ответ 1

После копания в источниках Android я понимаю, как отправить фокус на ViewGroup детей. Например, у меня есть пользовательский ViewGroup с несколькими EditText полями внутри. Когда пользователь нажимает ViewGroup (за пределами каждого EditText), я хочу отправить фокус на одно из полей.

Чтобы сделать это, нам нужно установить способность потомка к FOCUS_AFTER_DESCENDANTS. Это означает, что мы можем обрабатывать событие фокусировки до, наш пользовательский вид попытается сфокусироваться:

setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);


Следующим шагом является переопределить метод onRequestFocusInDescendants, он будет вызываться перед пользовательским представлением requestFocus, если установлен флаг FOCUS_AFTER_DESCENDANTS. В этом методе мы можем запросить фокус для ребенка:

@Override
protected boolean onRequestFocusInDescendants(final int dir, final Rect rect) {
    return getChildAt(this.target).requestFocus();
}

Одна важная вещь с этим методом: если мы вернем true здесь, наше пользовательское представление не будет запрашиваться для фокусировки (только с FOCUS_AFTER_DESCENDANTS).

Таким образом, мы можем изменить поле target, чтобы изменить, какой дочерний объект будет сфокусирован при нажатии ViewGroup.

<ч/" > Для лучшего понимания вы можете найти метод requestFocus в ViewGroup в источниках Android.