¿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>

¿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.


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.


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


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.


1

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

yourScrollView.fullScroll(ScrollView.FOCUS_UP);

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;

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.


1

Agregue estas dos líneas en su ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"

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é.


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í .


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 :)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.