¿Por qué mi actividad de Android siempre comienza a desplazarse hacia abajo?

91

Cada vez que comienzo esta actividad, siempre comienza tocando fondo: se desplaza hasta el final. No estoy haciendo nada extraño en la actividad OnCreate (o en cualquier otro lugar) que esperaría cambiar la posición de desplazamiento. He intentado establecer el enfoque en el control enfocable superior y en el método scrollto, pero ninguno de ellos funciona. Además, ninguna de mis otras actividades tiene este problema. Aquí está el diseño:

<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>
MrGibbage
fuente
¿Cómo trataste exactamente de cambiar el enfoque?
devmiles.com
1
utilizando el método fulscroll como se describe a continuación y el método scrollto como también se describe a continuación. No necesariamente me importa arreglarlo de esta manera, pero debe haber una razón por la que está comenzando así y prefiero arreglarlo corrigiéndolo.
MrGibbage

Respuestas:

306

Cuando Android inicia una actividad, es necesario centrarse en cierto control. Cuando no hay un control designado para enfocarse, el sistema elige el primer control elegible que desea enfocarse. Si se establece la siguiente propiedad en su LinearLayout - android:focusableInTouchMode="true"su LinearLayoutse centrará en el arranque y el nivel de actividad que se desplaza a EditTextla parte inferior.

devmiles.com
fuente
No funciona en mi GridLayout. Tengo un GridView en el medio del diseño y se enfoca cada vez.
Iqbal
2
Me rasqué la cabeza durante un día completo y no pude encontrar por qué estaba sucediendo en una sola actividad en particular y todavía no entiendo ya que no he habilitado el enfoque en ninguna vista. Pero gracias a ti, logré solucionar este problema. Sería genial si alguien pudiera arrojar algo de luz sobre cuál podría ser la posible razón, ya que no hay nada nuevo que esté haciendo en la nueva actividad.
Shubhral
2
Una nota importante: esto se debe agregar como propiedad al LinearLayoutinterior del ScrollView, no a la vista de desplazamiento en sí.
Boris Strandjev
@BorisStrandjev nota muy importante. Debería agregarse a la respuesta. Por cierto, gracias por eso: P
Coreggon
Literalmente se menciona en la respuesta.
devmiles.com
35

En lugar de contaminar elementos en su diseño, puede agregar esto a su Actividad / Clase:

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

De esta manera, no es un elemento dentro de su scrollView que se enfoca, es su scrollView como contenedor el que obtiene el primer enfoque, moviéndose a la vista secundaria después de esto.

Graeme
fuente
Parcialmente funciona para mí cuando intento establecer la altura de ListView en función de los niños dentro de ScrollView
Konstantin Konopko
¡Esto ayudó! (mientras que los mismos atributos en xml no funcionaron ..)
Matan Dahan
¡Funciona de maravilla! Thx
Bogy
Me funcionó, pero agregué esta línea: scrollView.fullScroll (ScrollView.FOCUS_UP) Ambos por separado no funcionaron.
Juan Giorello
3

Puedes probar este código:

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

[N: B] [enlace de referencia] 1

Comunidad
fuente
1
es una buena opción, pero simula un tirón después de la apertura, así que creo que no es una buena experiencia de usuario
iBabur
2

Junto con lo que dijo devmiles.com.

Si establece la siguiente propiedad en su LinearLayout - android: focusableInTouchMode = "true", su LinearLayout se centrará en el inicio y su actividad no se desplazará a EditText en la parte inferior.

Si llama a requestLayout () en una vista en la parte inferior de su diseño lineal, podría robar el foco de su vista superior. Así que simplemente llame a requestFocus () en la vista más superior en el diseño lineal después de llamar a requestLayout () en una vista inferior.

luca992
fuente
1

¿Ha intentado utilizar el método fullScroll? Http: //developer.android.com/reference/android/widget/ScrollView.html#fullScroll (int)

yourScrollView.fullScroll(ScrollView.FOCUS_UP);
Miguel
fuente
1

Para el desarrollo de Xamarin Android, si desea hacer la solución @Graeme, entonces:

// Set Focus to ScrollView
ScrollView scrollView = (ScrollView)FindViewById(Resource.Id.scrollView);
scrollView.FocusableInTouchMode = true;
scrollView.DescendantFocusability = Android.Views.DescendantFocusability.BeforeDescendants;
Asher Garland
fuente
1

Simplemente haz que no se pueda enfocar en onCreate ()

editText.setFocusable(false);

y use

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

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

 ......
 };

y no se desplazará hacia abajo hasta Edittext la próxima vez que se cree un fragmento o actividad.

altavoz codificado
fuente
1

Agregue estas dos líneas en su ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"
Hemendra Gangwar
fuente
0

No sé por qué, pero podrías experimentar con

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

en tu onCreatepara desplazarlo manualmente hasta donde quieras que esté.

zapl
fuente
0

scrollView.requestFocus(View.FOCUS_UP)resolvió mi problema cuando quería que la vista superior fuera visible. Especificar el parámetro de dirección al método requestFocus(int direction)es una buena forma de controlar la ScrollViewposición. Más detalles aquí .

Amit
fuente
0

En mi caso tenía un VideoViewinterior un ConstraintLayoutinterior a ScrollView. El VideoViewsiempre estaba robando el foco, y hay problemas con él . La solución es utilizar un TextureView. Espero que esto ayude a alguien, me costó al menos una hora :)

Daniel Wilson
fuente