У меня есть макет, и я хочу программно переключать фокус между представлениями. Мне довелось реализовать то, что вращает фокус, как группу представлений. У моего макета есть 3 элемента: текстовое представление и 2 кнопки:
<?xml version="1.0" encoding="utf-8"?>
<AccessContainer2 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AccessActivity">
<TextView
android:id="@+id/text_hello_world"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Hello World!"
android:nextFocusForward="@id/button_option_1"
android:focusable="true"
android:focusableInTouchMode="true">
<requestFocus/>
</TextView>
<LinearLayout
android:id="@+id/buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="afterDescendants">
<Button
android:id="@+id/button_option_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Option 1"
android:nextFocusForward="@id/button_option_2"
android:focusable="true"
android:focusableInTouchMode="true" />
<Button
android:id="@+id/button_option_2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Option 2"
android:nextFocusForward="@id/text_hello_world"
android:focusable="true"
android:focusableInTouchMode="true" />
</LinearLayout>
</AccessContainer2>
Я попытался определить «прямую» фокусировку для каждого из 3 фокусируемых элементов в виде текстового представления, кнопка 1, кнопка 2 и возвращаемся к текстовому представлению.
Мой код в моей группе представлений выглядит следующим образом:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final View currentFocus = getFocusedChild();
if (currentFocus == null) {
Log.w(TAG, "No current focus!");
} else {
Log.i(TAG, String.format("Currently focused child view ID: %s", getId(currentFocus)));
View newFocus = focusSearch(currentFocus, FOCUS_FORWARD);
Log.i(TAG, String.format("New child to focus view ID: %s", getId(newFocus)));
if (!newFocus.requestFocus()) {
Log.w(TAG, String.format("Failed to focus new child view ID: %s", getId(newFocus)));
}
}
return true;
}
Итак,
- Найти текущий фокус.
- Найдите из этого следующий "прямой" фокус.
- Установите его на текущий фокус.
Однако я получаю такой результат:
04-08 14:51:33.600 14232 14232 I AccessContainer2: Currently focused child view ID: com.clover.accesswork:id/text_hello_world
04-08 14:51:33.600 14232 14232 I AccessContainer2: New child to focus view ID: com.clover.accesswork:id/button_option_1
04-08 14:51:34.721 14232 14232 I AccessContainer2: Currently focused child view ID: com.clover.accesswork:id/buttons
04-08 14:51:34.724 14232 14232 I AccessContainer2: New child to focus view ID: com.clover.accesswork:id/text_hello_world
Таким образом, при первом касании он находит button_option_1 в качестве следующего фокуса, но когда я вызываю на нем фокус запроса, он устанавливает контейнер (кнопки) этого представления в качестве фокуса ... хотя я явно сказал, что макет не фокусируемость и то, что он должен предпочитать фокусировать своих потомков (хотя я не думаю, что это должно требоваться на линейном расположении, а только на попытках).
Есть идеи?