ScrollView禁用焦点移动

问题描述 投票:20回答:8

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

<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上吗?

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

谢谢!

android focus android-scrollview
8个回答
45
投票

我以为我会分享我的解决方案。即使其他一些答案的评论声明您无法覆盖此行为,但事实并非如此。一旦覆盖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将不再惹你的焦点。


15
投票

我也遇到过这样的问题。帮助我的唯一方法是扩展滚动视图并覆盖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);
    }

9
投票

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

当我只处理ScrollView内部的EditTexts时,只覆盖onRequestFocusInDescendants()才能很好地工作,但是当我开始添加多个View类型时,它的效果并不好。

只有压倒getFocusables()根本不起作用。

覆盖onRequestFocusInDescendants()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>();
  }

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

}

7
投票

我尝试了在这里发布的所有解决方案,但要么在某些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>();
  }

}

3
投票

尝试从源中删除问题(编辑:即将其移动到XML文件)。

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

android:focusable="false"
android:focusableInTouchMode="false"

1
投票

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

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

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

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

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

我希望它有所帮助。


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>

0
投票

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

container.setFocusable( false );
© www.soinside.com 2019 - 2024. All rights reserved.