我有一个简单的输入表格;它是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上吗?
我知道这可能是一个功能,但我需要禁用它。
谢谢!
答案 0 :(得分: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
不再会影响您的注意力。
答案 1 :(得分: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);
}
答案 2 :(得分: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 :(得分:7)
对我有用的是结合@ 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;
}
}
答案 4 :(得分:3)
尝试从源中删除问题(编辑:,即将其移至XML文件)。
首先,必须有一个可聚焦的元素才能实现。使该滚动中包含的所有可聚焦元素成为不可聚焦的元素。在视图膨胀并可见后,使它们可聚焦。
android:focusable="false"
android:focusableInTouchMode="false"
答案 5 :(得分:1)
我找到了另一个适用于我的问题的简单解决方案。
我的ScrollView
顶部有一个EditText
,之后是一个TextViews,RatingBars和Buttons的大列表。 Buttons启动AlertDialogs,当它们弹出时,ScrollView
移动到顶部,移动到仍然具有焦点的EditText
。
要解决此问题,我在活动的onClick
方法中设置requestFocusFromTouch()
到点击的视图(在本例中为Button)。
public void onClick(View v) {
v.requestFocusFromTouch();
...
}
现在,当我点击Button
时,ScrollView
移动并将Button
放在屏幕中央,这正是我想要的。
我希望它有所帮助。
答案 6 :(得分: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;
}
}
答案 7 :(得分: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>
答案 8 :(得分:0)
今天发生在我身上,基本上我是在一些现有视图之间以编程方式添加View,并且Scroll会自动移动以关注该视图。我刚才做的是:
container.setFocusable( false );
答案 9 :(得分:0)
这为我解决了这个问题。它可能并非在所有情况下都适用,但是对我以编程方式完成滚动的人来说效果很好:
View originalFocus = getCurrentFocus();
scroller.fullScroll(View.FOCUS_DOWN);
if (originalFocus!=null) {originalFocus.requestFocusFromTouch();}