Jak zapobiec przewijaniu widoku scrollview do widoku internetowego po załadowaniu danych?

107

Mam więc fascynujący problem. Pomimo tego, że nie przewijam widoku ręcznie ani programowo, mój WebView jest automatycznie przewijany po załadowaniu danych w nim zawartych.

Mam fragment w przeglądarce. Kiedy pierwszy raz ładuję pager, działa zgodnie z oczekiwaniami i wszystko jest pokazane. Ale kiedy „odwrócę stronę”, dane zostaną załadowane, a WebView wyskakuje na górę strony, ukrywając widoki nad nią, co jest niepożądane.

Czy ktoś wie, jak temu zapobiec?

Mój układ wygląda tak:

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

Nie skupiam się też na niczym. Domyślnie wydaje się, że po załadowaniu automatycznie przewija się do WebView. Jak temu zapobiec?

Navarr
źródło
dlaczego dokładnie potrzebujesz ScrollView, ponieważ WebView jest przewijalny?
znat
Aby niektóre aspekty nie były widoczne w widoku sieci Web, zamiast renderować je jako HTML. Szybkość i jakość.
Navarr
1
mjp66 ma najlepszą odpowiedź - być może powinieneś przyjąć jego odpowiedź
AndrewS

Odpowiedzi:

43

Możesz po prostu dodać to do swojego LinearLayout: android: focusableInTouchMode = "true". Mi to pasuje.

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >
Peter Nguyen
źródło
4
Działa bez skutków ubocznych!
Vaibhav Jani
267

Miałem ten sam problem, po godzinach wypróbowywania kilku pomysłów, co w końcu zadziałało, to po prostu dodanie descendantFocusabilityatrybutu do ScrollView zawierającego LinearLayout z wartością blocksDescendants. W Twoim przypadku:

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

Od tamtej pory problem się nie powtórzył.

mjp66
źródło
3
Czy ma to jakikolwiek negatywny wpływ na dostępność tych kontroli?
Cory Trese
34
Zauważ, że jeśli istnieją widoki podrzędne, takie jak EditText, ta metoda spowoduje, że staną się nieedytowalne.
djhworld
2
To pytanie / odpowiedź nie pojawia się podczas wyszukiwania słów autoprzewijanie ScrollView Webview, a powinno. Może ten komentarz pomoże! Miałem ten sam problem z używaniem WebViewFragment i nie znalazłem tego pytania nawet po wielu poszukiwaniach, dopóki nie opublikowałem własnego pytania (teraz zostało usunięte).
Colin M.
1
Podczas pracy nad projektem Xamarin.Android wystąpił problem z automatycznym przewijaniem w widoku przewijania z wieloma widokami siatki, wypełniony asynchronicznie pobranymi obrazami. To rozwiązanie działało tak doskonale, że na pierwszy rzut oka trudno było w to uwierzyć i musiałem je ponownie przetestować.
YumeYume,
1
Ten sam problem dotyczy również reklam w RecyclerView. Twoje rozwiązanie działa również w tym przypadku :)
Minas Mina
26

Powinieneś utworzyć nową klasę rozszerzającą ScrollView, a następnie Override requestChildFocus:

public class MyScrollView extends ScrollView {

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

Następnie w układzie XML, używając:

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

To działa dla mnie. ScrollView nie będzie już automatycznie przewijać do WebView.

user1417127
źródło
5
Potrzebni również konstruktorzy: 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

Dodanie tych linii do głównego układu rozwiązuje problem

android:descendantFocusability="blocksDescendants"
arun-r
źródło
4

Lubię to:

<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
źródło
4

Prawdopodobnie są ludzie, którzy mają ten sam problem, co ja, więc pomogę.

Próbowałem umieścić android: descendantFocusability = "beforeDescendants" w moim głównym ScrollView w następujący sposób:

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

i to nie działało, więc musiałem ustawić RelativeLayout jako element nadrzędny ScrollView i umieścić android: descendantFocusability = "beforeDescendants" jako element nadrzędny.

Więc rozwiązałem to, wykonując następujące czynności:

<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
źródło
-2

Musiałem użyć w pełni kwalifikowanej nazwy dla MyScrollView, w przeciwnym razie otrzymałem wyjątek inflate.

<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
źródło