Подтвердить что ты не робот

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

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

Спасибо!

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

}

Ответ 4

Что сработало для меня, было сочетание ответов @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;
  }

}

Ответ 5

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

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

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

Ответ 6

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

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

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

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

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

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

Ответ 7

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

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

container.setFocusable( false );