Comment empêcher une vue de défilement de défiler vers une vue Web après le chargement des données?

107

J'ai donc un problème fascinant. Bien que je ne fasse pas défiler ma vue manuellement ou par programme, ma WebView fait automatiquement défiler la vue après le chargement des données à l'intérieur.

J'ai un fragment dans un viewpager. Lorsque je charge le pager pour la première fois, il fonctionne comme prévu et tout est affiché. Mais une fois que je "retourne la page", les données se chargent et la WebView apparaît en haut de la page, cachant les vues au-dessus, ce qui n'est pas souhaitable.

Quelqu'un sait-il comment empêcher que cela se produise?

Ma mise en page ressemble à ceci:

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

Je ne me concentre pas non plus sur quoi que ce soit. Par défaut, il semble faire défiler automatiquement vers WebView après son chargement. Comment éviter cela?

Navarr
la source
pourquoi exactement avez-vous besoin de ScrollView car une WebView est défilable?
znat
Pour garder certains aspects hors de la vue Web au lieu de les rendre au format HTML. Pour la rapidité et la qualité.
Navarr
1
mjp66 a la meilleure réponse - vous devriez peut-être accepter sa réponse
AndrewS

Réponses:

43

Vous pouvez simplement l'ajouter à votre LinearLayout: android: focusableInTouchMode = "true". Ça marche pour moi.

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >
Peter Nguyen
la source
4
Fonctionne sans effets secondaires!
Vaibhav Jani
267

J'ai eu le même problème, après des heures à essayer plusieurs idées, ce qui a finalement fonctionné pour moi était simplement d'ajouter l' descendantFocusabilityattribut au ScrollView contenant LinearLayout, avec la valeur blocksDescendants. Dans ton cas:

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

Je n'ai plus eu le problème depuis.

mjp66
la source
3
Cela a-t-il un impact négatif sur l'accessibilité de ces contrôles?
Cory Trese
34
Notez que s'il existe des vues enfants comme EditText, cette méthode les rendra non modifiables.
djhworld
2
Cette question / réponse n'apparaît pas lorsque vous recherchez les mots ScrollView Webview autoscroll, et cela devrait. Peut-être que ce commentaire vous aidera! J'ai eu le même problème avec l'utilisation d'un WebViewFragment et je n'ai pas trouvé cette question même après de nombreuses recherches jusqu'à ce que je publie ma propre question (maintenant supprimée).
Colin M.
1
Travailler sur un projet Xamarin.Android, a eu des problèmes de défilement automatique dans une vue de défilement avec plusieurs vues de grille, remplies de manière asynchrone avec des images téléchargées. Cette solution fonctionnait si parfaitement que j'ai eu du mal à y croire à première vue et j'ai dû la tester à nouveau.
YumeYume
1
Le même problème se produit également pour les annonces dans un RecyclerView. Votre solution fonctionne également dans ce cas :)
Minas Mina
26

Vous devez créer une nouvelle classe extend ScrollView, puis Override requestChildFocus:

public class MyScrollView extends ScrollView {

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

Puis dans votre mise en page xml, en utilisant:

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

Ça marche pour moi. Le ScrollView ne défilera plus automatiquement vers WebView.

user1417127
la source
5
Constructeurs également nécessaires: 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

L'ajout de ces lignes dans la mise en page principale résout le problème

android:descendantFocusability="blocksDescendants"
arun-r
la source
4

Comme ça:

<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
la source
4

Il y a probablement des gens qui ont le même problème que moi, alors je vais vous aider.

J'essayais de mettre android: descendantFocusability = "beforeDescendants" dans mon ScrollView principal comme suit:

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

et cela ne fonctionnait pas, j'ai donc dû faire d'un RelativeLayout le parent de ScrollView, et placer l' androïde: descendantFocusability = "beforeDescendants" dans le parent également.

Je l'ai donc résolu en procédant comme suit:

<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
la source
-2

J'ai dû utiliser le nom complet pour MyScrollView, sinon j'ai eu une exception gonflée.

<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
la source