¿Cómo evitar que una vista de desplazamiento se desplace a una vista web después de cargar los datos?

107

Entonces tengo un problema fascinante. A pesar de que no estoy desplazando mi vista de forma manual o programática, mi WebView se desplaza automáticamente hasta después de que se cargan los datos que contiene.

Tengo un fragmento en un visor. Cuando cargo el buscapersonas por primera vez, funciona como se esperaba y se muestra todo. Pero una vez que "volteo la página", los datos se cargan y WebView aparece en la parte superior de la página, ocultando las vistas sobre ella, lo cual no es deseable.

¿Alguien sabe cómo evitar que esto suceda?

Mi diseño se ve así:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/background" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/article_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="2dp"
            android:text="Some Title"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/article_title"
            android:textStyle="bold" />

        <LinearLayout
            android:id="@+id/LL_Seperator"
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:background="@color/text"
            android:orientation="horizontal" >
        </LinearLayout>

        <WebView
            android:id="@+id/article_content"
            android:layout_width="match_parent"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/article_link"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:text="View Full Article"
            android:textColor="@color/article_title"
            android:textStyle="bold" />
    </LinearLayout>

</ScrollView>

Tampoco me estoy concentrando en nada. De forma predeterminada, parece desplazarse automáticamente a WebView después de que se haya cargado. ¿Cómo puedo prevenir esto?

Navarr
fuente
¿Por qué exactamente necesita ScrollView ya que WebView es desplazable?
znat
Para mantener algunos aspectos fuera de la vista web en lugar de representarlos como HTML. Por rapidez y calidad.
Navarr
1
mjp66 tiene la mejor respuesta - tal vez debería aceptar su respuesta
AndrewS

Respuestas:

43

Simplemente puede agregar esto a su LinearLayout: android: focusableInTouchMode = "true". Esto funciona para mi.

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >
Peter Nguyen
fuente
4
¡Funciona sin efectos secundarios!
Vaibhav Jani
267

Tuve el mismo problema, después de horas de probar varias ideas, lo que finalmente funcionó para mí fue simplemente agregar el descendantFocusabilityatributo al LinearLayout que contiene ScrollView, con el valor blocksDescendants. En tu caso:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants" >

No he vuelto a tener el problema desde entonces.

mjp66
fuente
3
¿Tiene esto algún impacto negativo en la accesibilidad de estos controles?
Cory Trese
34
Tenga en cuenta que si hay vistas secundarias como EditText, este método hará que no se puedan editar.
djhworld
2
Esta pregunta / respuesta no aparece cuando busca las palabras ScrollView Webview autodesplazamiento, y debería. ¡Quizás este comentario ayude! Tuve el mismo problema con el uso de WebViewFragment y no encontré esta pregunta incluso después de muchas búsquedas hasta que publiqué mi propia pregunta (ahora eliminada).
Colin M.
1
Al trabajar en un proyecto de Xamarin.Android, tenía problemas de desplazamiento automático en una vista de desplazamiento con varias vistas de cuadrícula, pobladas de forma asincrónica con imágenes descargadas. Esta solución funcionó tan perfectamente que tuve problemas para creerla a primera vista y tuve que probarla nuevamente.
YumeYume
1
El mismo problema ocurre con los anuncios en un RecyclerView. Su solución también funciona en ese caso :)
Minas Mina
26

Debe crear una nueva clase extender ScrollView, luego anular requestChildFocus:

public class MyScrollView extends ScrollView {

    @Override 
    public void requestChildFocus(View child, View focused) { 
        if (focused instanceof WebView ) 
           return;
        super.requestChildFocus(child, focused);
    }
}

Luego, en su diseño xml, usando:

<MyScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/background" >

Funciona para mi. ScrollView ya no se desplazará automáticamente a WebView.

usuario1417127
fuente
5
También se necesitan constructores: public ExtendedScrollView(Context context) { super(context); } public ExtendedScrollView( Context context, AttributeSet attributeSet) { super(context, attributeSet); } public ExtendedScrollView( Context context, AttributeSet attributeSet, int defStyle) { super(context, attributeSet, defStyle); }
Erik B
5

Agregar estas líneas en el diseño principal resuelve el problema

android:descendantFocusability="blocksDescendants"
arun-r
fuente
4

Me gusta esto:

<com.ya.test.view.MyScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:descendantFocusability="beforeDescendants"
        android:focusable="true"
        android:focusableInTouchMode="true" >
YaC King
fuente
4

Probablemente hay personas que tienen el mismo problema que yo, así que ayudaré.

Estaba tratando de poner android: descenddantFocusability = "beforeDescendants" en mi ScrollView principal de la siguiente manera:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="beforeDescendants">
    /*my linearlayout or whatever to hold the views */

y no estaba funcionando, así que tuve que convertir un RelativeLayout en el padre de ScrollView y colocar android: descenddantFocusability = "beforeDescendants" en el padre también.

Así que lo resolví haciendo lo siguiente:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
/*my linearlayout or whatever to hold the views */
James
fuente
-2

Tuve que usar el nombre completo para MyScrollView, de lo contrario obtuve una excepción de inflado.

<com.mypackagename.MyScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/background" >
Cathal Coffey
fuente