Перемещение фокуса ScrollView

У меня простая форма ввода; Это вертикальный LinearLayout с EditTexts внутри ScrollView.

<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, выбранном в данный момент прикосновением?

Я понимаю, что это может быть особенностью, но мне нужно ее отключить.

Благодаря!

Просто подумал, что я поделюсь своим решением. Несмотря на то, что некоторые из комментариев другого ответа утверждают, что вы не можете переопределить это поведение, это неверно. Это поведение останавливается, как только вы переопределяете метод 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 больше не будет работать с вашим фокусом.

У меня тоже была такая проблема. Единственный способ, который помог мне, – расширить прокрутку и переопределить

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

Я пробовал все решения, размещенные здесь, но либо не работал на некоторых версиях 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>(); } } 

Что сработало для меня, было сочетание ответов @ dmon и @ waj.

Только переопределение onRequestFocusInDescendants() отлично поработало, когда я имел дело только с EditTexts внутри ScrollView, но когда я начал добавлять несколько типов 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; } } 

Попробуйте отрезать проблему от источника ( отредактируйте: т.е. переместите его в файл XML).

Во-первых, для этого должен быть сосредоточенный элемент. Сделайте все сосредоточенные элементы, содержащиеся в этом прокрутке, в элементы без фокусировки. Сделайте их фокусируемыми после того, как вид завышен и будет виден.

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

Я нашел еще одно простое решение, которое работает для моей проблемы.

У меня есть ScrollView с EditText в верхней части, а после него – большой список TextViews, RatingBars и Buttons. Кнопки запускают AlertDialogs, и когда они всплывают, ScrollView перемещается вверх, в EditText, который остается в центре внимания.

Чтобы решить эту проблему, я установил в методе onClick Activity функцию requestFocusFromTouch () для щелкнутого представления (в данном случае кнопки).

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

Итак, теперь, когда я нажимаю кнопку Button, ScrollView перемещается и помещает эту кнопку в центр экрана, это было именно то, что я хотел.

Надеюсь, это поможет.

Для такого поведения используйте 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> 

Случилось со мной сегодня, в основном я добавлял View программно между некоторыми существующими представлениями, а Scroll автоматически перемещался, чтобы сфокусировать это представление. То, что я только что сделал, следующее:

 container.setFocusable( false );