Почему моя активность в Android всегда начинает прокручиваться вниз?

91

Всякий раз, когда я начинаю это действие, оно всегда начинается с самого низа - прокручивается до самого низа. Я не делаю ничего странного в действии OnCreate (или где-либо еще), что я ожидал бы изменить положение прокрутки. Я попытался установить фокус на самый верхний фокусируемый элемент управления и метод scrollto, но ни один из них не работает. Кроме того, ни в одной другой моей деятельности нет этой проблемы. Вот макет:

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/edit_refresh_update_header"
            android:textSize="18sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Variable:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_variables_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Network:"
            android:textSize="18sp"/>

        <RadioGroup
            android:id="@+id/widget1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical">

            <RadioButton
                android:text="Web"
                android:id="@+id/edit_refresh_update_rb_web"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"
                android:checked="true"/>

            <RadioButton
                android:text="Socket Server"
                android:id="@+id/edit_refresh_update_rb_socket_server"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"/>
        </RadioGroup>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server request type:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_socket_server_req_types_spinner"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server body:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_ss_body"
            android:layout_height="wrap_content"
            android:enabled="false"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Url:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_url"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <Button
            android:text="Save refresh update"
            android:id="@+id/edit_refresh_save_btn"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginBottom="20dp"
            android:layout_alignParentBottom="true"
            android:onClick="SaveRefreshUpdate">
        </Button>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>
    </LinearLayout>
</ScrollView>
Мистер Гиббидж
источник
Как именно вы пытались изменить фокус?
devmiles.com
1
используя метод прокрутки, как описано ниже, и метод прокрутки, как описано ниже. Я не обязательно возражаю против того, чтобы исправить это таким образом, но должна быть причина, по которой это начинается так, и я бы предпочел исправить это, исправив это.
MrGibbage

Ответы:

307

Когда Android начинает действие, необходимо сосредоточить внимание на некоторых элементах управления. Когда нет назначенного элемента управления, на который следует сфокусироваться, система выбирает первый подходящий элемент управления, которому требуется фокус. Если вы установите следующее свойство в своем LinearLayout - android:focusableInTouchMode="true"вы LinearLayoutбудете сосредоточены на запуске, а ваша активность не будет прокручиваться EditTextвниз.

devmiles.com
источник
Не работает в моем GridLayout. У меня есть GridView в середине макета, и он каждый раз получает фокус.
Iqbal
2
Я почесал голову целый день и не мог понять, почему это происходит только в одном конкретном действии, и я до сих пор не понимаю, так как я не включил фокусировку ни на одном виде. Но благодаря вам мне удалось исправить эту проблему. Было бы здорово, если бы кто-нибудь мог пролить свет на возможную причину, поскольку в этом новом мероприятии я не делаю ничего нового.
Shubhral
2
Важное примечание: это должно быть добавлено как свойство LinearLayoutвнутри ScrollView, а не в само представление прокрутки.
Борис Странджев
@BorisStrandjev очень важное замечание. К ответу следует добавить. Кстати, на этом спасибо: P
Coreggon
Об этом буквально сказано в ответе.
devmiles.com
35

Вместо того, чтобы загрязнять элементы в вашем макете, вы можете добавить это в свой Activity / Class:

    ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
    scrollView.setFocusableInTouchMode(true); 
    scrollView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

Таким образом, это не элемент в вашем scrollView, получающий фокус, это ваш scrollView как контейнер, который получает первый фокус, переходя после этого на дочернее представление.

Грэм
источник
Частично работает для меня, когда я пытаюсь установить высоту ListView на основе дочерних элементов внутри ScrollView
Константин Конопко
Это помогло! (при этом те же атрибуты в xml не работали ..)
Матан Дахан
Работает как шарм! Спасибо
Bogy
У меня это сработало, но я добавил эту строку: scrollView.fullScroll (ScrollView.FOCUS_UP) Оба по отдельности не работали.
Хуан Джорелло
3

Вы можете попробовать этот код:

scroller.post(new Runnable() { 
    public void run() { 
        scroller.fullScroll(ScrollView.FOCUS_DOWN); 
    } 
}); 

[N: B] [ссылка] 1

Сообщество
источник
1
это хороший вариант, но он имитирует рывок после открытия, поэтому я думаю, что это не лучший пользовательский опыт
iBabur
2

Наряду с тем, что сказал devmiles.com.

Если вы установите следующее свойство в своем LinearLayout - android: focusableInTouchMode = "true", ваш LinearLayout будет сфокусирован на запуске, и ваша активность не будет прокручиваться до EditText внизу.

Если вы вызываете requestLayout () в представлении в нижней части линейного макета, это может отвлечь внимание от самого верхнего представления. Поэтому просто вызовите requestFocus () в самом верхнем представлении линейного макета после вызова requestLayout () в нижнем представлении.

luca992
источник
1

Вы пробовали использовать метод fullScroll? Http: //developer.android.com/reference/android/widget/ScrollView.html#fullScroll (int)

yourScrollView.fullScroll(ScrollView.FOCUS_UP);
Майк
источник
1

Для разработки Xamarin Android, если вы хотите использовать решение @Graeme, выполните следующие действия:

// Set Focus to ScrollView
ScrollView scrollView = (ScrollView)FindViewById(Resource.Id.scrollView);
scrollView.FocusableInTouchMode = true;
scrollView.DescendantFocusability = Android.Views.DescendantFocusability.BeforeDescendants;
Ашер Гарланд
источник
1

Просто сделайте это не фокусируемым в onCreate ()

editText.setFocusable(false);

и использовать

editText.setOnClickListener(new ....){
 ......
  editText.setFocusable(true);
  editText.setFocusableInTouchMode(true);
  editText.requestFocus();

  showSoftKeyboard(); //Use InputMethodManager to open soft Keyboard

 ......
 };

и он не будет прокручиваться до Edittext в следующий раз, когда будет создан фрагмент или действие.

диктор
источник
1

Добавьте эти две строки в свой ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"
Хемендра Гангвар
источник
0

Я не знаю почему, но вы можете поэкспериментировать с

ScrollView sv = (ScrollView) findViewById(R.id.scroll);
sv.scrollTo(0,0);

в вашем, onCreateчтобы вручную прокрутить его туда, где вы хотите.

запл
источник
0

scrollView.requestFocus(View.FOCUS_UP)решил мою проблему, когда я хотел, чтобы был виден вид сверху. Указание параметра направления для метода requestFocus(int direction)- хороший способ контролировать ScrollViewположение. Подробнее здесь .

Амит
источник
0

В моем случае я был VideoViewвнутри ConstraintLayoutвнутри ScrollView. Они VideoViewвсегда отвлекали внимание, и с этим есть проблемы . Решение - использовать TextureView. Надеюсь, это кому-то поможет, это стоило мне как минимум часа :)

Дэниел Уилсон
источник