以编程方式“旋转”焦点

问题描述 投票:0回答:1

我有一个布局,我想以编程方式在视图之间切换焦点。我碰巧正在实现将焦点作为视图组旋转的东西。我的布局包含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并返回文本视图。

我的代码,在我的视图组中,impl看起来像:

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

所以,

  1. 查找当前焦点。
  2. 从中找到下一个“前进”焦点。
  3. 将其设置为当前焦点。

但是,我得到了这个结果:

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作为下一个焦点,但是当我调用请求焦点时,它将视图的容器(按钮)设置为具有焦点...即使我明确地告诉它布局不可聚焦并且它应该优先关注其后代(尽管我认为线性布局不要求这样做,而只是尝试一下)。

有什么想法吗?

android android-layout android-view
1个回答
0
投票

这是一个“ RTFM”错误。事实证明,getFocusedChild()被记录为:

返回此视图的焦点子级(如果有)。 孩子可能有焦点或包含焦点。

因此,在这种情况下,它将返回包含焦点的视图,而不是包含焦点的孩子。我编写了此函数来获取实际上具有焦点的子视图:

private View getFocused(ViewGroup vg) {
    View focused = vg.getFocusedChild();
    if (focused == null) {
        return null;
    }
    if (focused instanceof ViewGroup) {
        // Figure out if a child of the view group has focus
        // Recursion!
        View v = getFocused((ViewGroup) focused);
        if (v == null) {
            // The view group itself actually has focus
            return focused;
        } else {
            // A child of the view group had focus
            return v;
        }
    }
    // A non-view group child had focus
    return focused;
}
© www.soinside.com 2019 - 2024. All rights reserved.