28

我有一个简单的输入表格;它是一个垂直的 LinearLayout,在 ScrollView 中带有 EditTexts。

<ScrollView android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:padding="10dip"
                  android:gravity="center_vertical"
                  android:orientation="horizontal">
                  <TextView style="@style/Text"
                         android:text="Name"/>
                  <EditText style="@style/EditBox"/>
            </LinearLayout>
            <View style="@style/Divider"/>
            <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:padding="10dip"
                  android:gravity="center_vertical"
                  android:orientation="horizontal">
                  <TextView style="@style/Text"
                         android:text="Password"/>
                  <EditText style="@style/EditBox"/>
            </LinearLayout>               
            ... 
     </LinearLayout>
</ScrollView>

当用户滚动表单时,它会自动将焦点移到可见的 EditText 上。是否可以禁用此类行为并始终将注意力集中在当前通过触摸选择的 EditText 上?

我知道这可能是一项功能,但我需要禁用它。

谢谢!

4

10 回答 10

50

只是想我会分享我的解决方案。即使其他答案的一些评论指出您不能覆盖此行为,但事实并非如此。一旦您覆盖该onRequestFocusInDescendants()方法,此行为就会停止。所以只需创建您的 ScrollView 扩展来执行此操作:

public class NonFocusingScrollView extends ScrollView {

  public NonFocusingScrollView(Context context) {
    super(context);
  }

  public NonFocusingScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public NonFocusingScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
    return true;
  }

}

你完成了。ScrollView不会再扰乱你的注意力了。

于 2011-08-18T21:10:44.030 回答
16

我也遇到过这样的问题。帮助我的唯一方法是扩展滚动视图并覆盖 neigher

@Override
public ArrayList<View> getFocusables(int direction) {
    return new ArrayList<View>();
}

或者

@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
    return true;
}

但要覆盖ViewGroup.requestChildFocus(View child, View focused)方法如下:

    @Override
    public void requestChildFocus(View child, View focused) {
        // avoid scrolling to focused view
        // super.requestChildFocus(child, focused);
    }
于 2012-10-23T10:55:40.280 回答
11

对我有用的是结合@dmon 和@waj 的答案。

onRequestFocusInDescendants()当我只在 ScrollView 中处理 EditTexts 时,只有覆盖效果很好,但是当我开始添加多个 View 类型时,它并没有那么好用。

只有覆盖getFocusables()根本不起作用。

覆盖这两个onRequestFocusInDescendants()ANDgetFocusables()似乎在所有情况下都能很好地工作。

public class FixedFocusScrollView extends ScrollView {

  public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public FixedFocusScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public FixedFocusScrollView(Context context) {
    super(context);
  }

  @Override
  public ArrayList<View> getFocusables(int direction) {
      return new ArrayList<View>();
  }

  @Override
  protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
    return true;
  }

}
于 2015-06-09T16:24:43.757 回答
8

我尝试了此处发布的所有解决方案,但要么不适用于某些 Android 版本,要么它与其他一些行为混淆,例如在触摸和非触摸模式之间切换时(当您单击按钮或使用触控板时)。

我终于发现覆盖该方法getFocusables可以解决问题:

public class FixedFocusScrollView extends ScrollView {

  public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public FixedFocusScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public FixedFocusScrollView(Context context) {
    super(context);
  }

  @Override
  public ArrayList<View> getFocusables(int direction) {
    return new ArrayList<View>();
  }

}
于 2012-05-29T22:36:01.117 回答
4

尝试从源头上解决问题(编辑:即将其移动到 XML 文件)。

首先,必须有一个可聚焦的元素才能实现。使该滚动中包含的所有可聚焦元素成为不可聚焦元素。在视图膨胀并可见后使它们具有焦点。

android:focusable="false"
android:focusableInTouchMode="false"
于 2012-04-04T12:15:43.727 回答
1

我找到了另一个适用于我的问题的简单解决方案。

我在顶部ScrollView有一个EditText,在它之后,是一大堆 TextViews、RatingBars 和 Buttons。按钮启动 AlertDialogs,当它们弹出时,ScrollView移动到顶部,移动到EditText仍然具有焦点的那个。

为了解决这个问题,我在onClickActivity 的方法中设置requestFocusFromTouch()了单击的视图(在本例中为 Button)。

public void onClick(View v) {
    v.requestFocusFromTouch();
    ...
}

所以现在当我点击 aButton时,ScrollView移动并将其Button放在屏幕中央,这正是我想要的。

我希望它有所帮助。

于 2012-06-29T16:24:01.947 回答
1

这个方法很有效,可以重载computeScrollDeltaToGetChildRectOnScreen并返回0

public class NoScrollFocusScrollView extends ScrollView {

    public NoScrollFocusScrollView(Context context) {
        super(context);
    }

    public NoScrollFocusScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoScrollFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
        return 0;
    }
}

于 2020-09-02T07:28:20.023 回答
0

对于此类行为,请使用 nextFocusUp 和 nextFocusDown。

<EditText
    android:id="@+id/my_edit_text"
    android:nextFocusDown="@id/my_edit_text"
    android:nextFocusUp="@id/my_edit_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</EditText>
于 2011-03-21T10:31:38.687 回答
0

今天发生在我身上,基本上我是在一些现有视图之间以编程方式添加一个视图,并且滚动自动移动以聚焦该视图。我刚刚做的是以下内容:

container.setFocusable( false );
于 2014-01-28T07:59:31.690 回答
0

这为我解决了这个问题。它可能不适用于所有情况,但适用于以编程方式完成滚动的我:

View originalFocus = getCurrentFocus();
scroller.fullScroll(View.FOCUS_DOWN);
if (originalFocus!=null) {originalFocus.requestFocusFromTouch();}
于 2020-06-23T20:11:38.983 回答