【问题标题】:Programmatically "rotating" focus以编程方式“旋转”焦点
【发布时间】:2020-04-08 22:00:02
【问题描述】:

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

    这是一个“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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 2011-12-18
      • 2021-10-30
      • 2014-07-09
      • 2015-06-21
      • 2013-03-24
      • 1970-01-01
      • 2010-11-02
      相关资源
      最近更新 更多