2013-08-27 11 views
10

Mam układ z numerem ScrollView, który zawiera następujące widoki: ImageView, TextView, WebView, TextView. (To dlatego, że chciałbym, aby przewinąć całą sobą, a nie tylko zawartość WebView)WebView w ScrollView: "Widok zbyt duży, aby zmieścić się w pamięci podręcznej rysunku" - jak przerobić układ?

Po załadowaniu niektóre HTML w WebView, Otrzymuję następujący:

WARN/View(632): View too large to fit into drawing cache, needs 14236800 bytes, only 1536000 available 

... a zawartość WebView nie będzie wyświetlana. Po usunięciu ScrollView, ostrzeżenie zniknie i wszystko będzie dobrze, z tym wyjątkiem, że stracę pożądaną funkcję przewijania.

pierwsze: wiem, że próbuje użyć ScrollView wewnątrz innego ScrollView jest złe w ogóle, ale nie jestem w 100% pewien, że w każdym przypadku jest równoważne rozwiązanie bez użycia ScrollView ... Znaczy , oczywiście można umieścić zawartość ImageView s i TextView s w WebView, ale co z Button lub innymi elementami UI wymagającymi interakcji? Czy istnieje ogólny sposób rozwiązywania takich problemów bez rezygnacji z układu i przewijania wszystkiego naraz?

Dowiedziałem się, że nie jestem jedyny z tym problemem. Do innych przykładów, sprawdź te pytania - bez roztworu roboczego jeszcze:

+0

Wypróbuj rzeczy w tej odpowiedzi: http://stackoverflow.com/a/5274400/507810, aby wyłączyć przewijanie w WebView. To może poprawić sytuację. Jest to jednak ujęcie w ciemności z mojej strony. – FoamyGuy

+0

Miałem ten problem, gdy przypadkowo umieściłem przewijany widok w innym przewijanym widoku/pojemniku. Rozwiązaniem była zmiana kontenera na LinearLayout. Aby uzyskać więcej informacji, zobacz mój komentarz poniżej tej odpowiedzi: https://stackoverflow.com/a/37418736/1617737 –

Odpowiedz

14

Problem wydaje się być związane z akceleracji sprzętowej, która jest domyślnie włączona, jeśli poziom API jest> = 14.

Mam app z ScrollView, który zawiera szereg poglądów, że chcę, aby przewinąć jako pojedyncza jednostka podobna do oryginalnego plakatu - jeden z tych widoków jest widokiem sieciowym, który otacza swoją treść. Jeśli akceleracja sprzętowa jest włączona, a jest w ogóle złożona (obrazy, ramki itp.), Wówczas komunikat o błędzie pamięci podręcznej rysunku można zobaczyć w polu LogCat. Niektóre ekrany z 12 elementami działały, podczas gdy następny ekran z 13 elementami nie działał. Nie sądzę, że jest to liczba elementów, która robi różnicę, ale złożoność końcowego renderowanego ekranu.

Objawy są zazwyczaj puste WebView - inne widoki są wizualnie obecne i pełne. Od czasu do czasu widzę cały ekran pusty, ale mogło to być, póki mam do czynienia z różnymi sugestiami znalezionymi tutaj na SO.

Wiadomość nie zawsze jest widoczna. Na przykład widzę problem na Samsung Galaxy 4 Mini z 4.2.2, podczas gdy na innych urządzeniach 4.x, takich jak mój tani chiński klon Samsung S3 z 4.1.2, wszystko jest w porządku. Nie widziałem go na żadnym urządzeniu 1.x lub 2.x.

Próbowałem selektywnie wyłączyć akcelerację sprzętową w różnych widokach i układach w hierarchii widoku, ale na samym końcu akceleracja sprzętowa dla całej aplikacji w pliku manifestu z frustracji i widząc ile godzin zmarnowałem śledzenie tego.

Po wyłączeniu akceleracji sprzętowej wszystkie problemy zniknęły. Nie zauważam zauważalnych różnic w wydajności na żadnym z moich urządzeń. Prawdopodobnie urządzenia 1.x i 2.x nigdy w pierwszej kolejności nie używały akceleracji sprzętowej, a moje urządzenia 4.x muszą być wystarczająco szybkie, by radzić sobie z renderowaniem wyłącznie oprogramowania. Nie, że moje ekrany są tak skomplikowane.

Aktualizacja kwiecień 2015

Niestety komunikat ostrzegawczy jest z powrotem na Samsung Galaxy Mini 4 4.4.2 działa teraz nawet z akceleracji sprzętowej wyłączony. Mam widok internetowy z animacją otwierania/zamykania panelu JavaScript. Wszystko działa dobrze, z wyjątkiem tego, że początkowy układ (panel otwarty) podnosi te ostrzeżenia, a za każdym razem, gdy zamykam lub otwieram panel, również je dostaję. Te ostrzeżenia są teraz denerwujące, aplikacja działa dobrze.

+2

Działa dla mnie z Androidem: hardwareAccelerated = "false" .Dzięki. – duanbo1983

+0

Uratowałeś mnie. Dzięki! – mr5

+0

tak, ale jeśli zrobisz android: hardwareAccelerated = "false", wówczas osadzone filmy html5 nie będą odtwarzane w widoku internetowym ......... – aimiliano

-2

stworzyłem coś podobnego i wszystko, co było potrzebne, aby dodać do mojego WebView:

android:layout_height="match_parent" 
+0

Przepraszam, ale nie sądzę, by to rozwiązało problem z pamięcią podręczną rysunku; faktycznie używam tego w mojej problematycznej wersji. – Scorchio

-3

To działa dla mnie:

<WebView 
     android:id="@+id/wv" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scrollbars="horizontal"/> 
1

webView.setLayerType(WebView.LAYER_TYPE_NONE, null);

pracował dla mnie. W zależności od sprzętu, nie ma już pamięci na dodatkowy bufor poza ekranem, ponieważ WebView jest renderowany całkowicie, gdy jest osadzony w innym widoku przewijania.

Uważam, że to błąd w systemie Android, że nie jest automatycznie przywracany do tej (wolniejszej, ale działającej) opcji.

3

Jak wskazano w innych odpowiedziach, problem pojawia się, gdy aktywne jest przyspieszenie sprzętowe. Ale wyłączenie akceleracji sprzętowej dla całej aplikacji nie było dla mnie rozwiązaniem.

Pomyślałem, że mogę rozwiązać problem, ustawiając android:layerType="software" na ScrollView, który wyłącza akcelerację sprzętową dla ScrollView i jej zawartości.

<ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layerType="software"> 

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

     <FrameLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"> 
      ... 
     </FrameLayout> 

     <WebView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 

</ScrollView> 

Należy zauważyć, że może to mieć negatywny wpływ na wydajność, ponieważ renderowanie w oprogramowaniu jest zwykle wolniejsze.

+0

Uznaliśmy, że ta odpowiedź zadziałała, ale wydajność nie wydawała się wielka. Wtedy zdałem sobie sprawę, że coś musi być nie tak dla mnie, aby uzyskać ** Widok zbyt duży, aby zmieścić się w pamięci podręcznej rysunku ** ostrzeżenie w pierwszej kolejności ... Wtedy zaświtało mi, że mam 'ListView' (i tak jest przewijalnie) w 'NestedScrollView'. Więc zmieniłem 'NestedScrollView' na' LinearLayout' i teraz działa idealnie - bez potrzeby "android: layerType =" software "'. –

Powiązane problemy