2017-02-09 22 views
2

Я пишу приложение, которое мне нужно для WebView, чтобы служить механизмом веб-рендеринга для службы Android. Таким образом, WebView никогда не прикрепляется к окну. Однако я могу создавать моментальные снимки страниц, не помещая их в иерархию представлений, вручную измеряя и выкладывая представление (ViewGroup), а затем рисуя его в растровое изображение.Android Корректный рисунок после scrollTo()

Проблема заключается в том, как только я позвонить по нему scrollTo() представление не нарисует части страницы, которые были скрыты до свитка и зерновые культуры это, что-то вроде этого

scrolled a bit along x and y axis as well

WebView выложен задолго до того, нагрузки страницы запрашиваются с помощью следующего метода

private void layout(
     @NonNull final WebView webView, final int targetWidth, final int targetHeight) { 
    webView.measure(
      View.MeasureSpec.makeMeasureSpec(targetWidth, View.MeasureSpec.AT_MOST), 
      View.MeasureSpec.makeMeasureSpec(targetHeight, View.MeasureSpec.AT_MOST)); 

    webView.layout(0, 0, targetWidth, targetHeight); 
} 

растрового изображения захватывается с помощью следующего кода

private Bitmap capture(
     @NonNull final WebView webView) { 
    webView.setDrawingCacheEnabled(true); 
    webView.buildDrawingCache(); 

    final Bitmap bitmap = Bitmap.createBitmap(
      webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888); 

    final Canvas canvas = new Canvas(bitmap); 
    webView.draw(canvas); 

    webView.setDrawingCacheEnabled(false); 

    return bitmap; 
} 

Общая процедура выглядит следующим образом

layout(mWebView, maxWidth, maxHeight); 
// page is loaded 
mWebView.scrollTo(...); 
// here I've tried number of things like mWebView.invalidate(), mWebView.requestLayout() or mWebView.refreshDrawableState() 
final Bitmap bitmap = capture(mWebView); 

ВАЖНО: когда я загрузить страницу в WebView, который обычно прилагается к окну в пределах деятельности WebView получает прокручивается, где я хочу, и страница хорошо отображается.

В чем разница? Как это отличается от того, что делает андроид для WebView, когда он привязан к окну активности?

+0

Я уверен, что 'WebView' использует оптимизацию, где он не перерисовывает себя, если обнаруживает, что он не привязан к окну. Вы пробовали вызывать 'invalidate()' в WebView? Возможно, это может привести к полному переделке ... –

+0

Спасибо за ответ. Да. Я попробовал requestLayout(), а также сделал это после короткого (~ 1 с) таймаута после загрузки страницы. – foo

+0

Я посмотрел, трудно понять, что там происходит (WebView, WebViewChromium и т. Д.), Но могу сказать, что некоторые функции рисования/прокрутки требуют, чтобы WebView запускался в потоке пользовательского интерфейса/был прикреплен к иерархии представления , Кроме того, кажется, что 'View.invalidate()' [будет пропускать, если не видно] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/View.java#View.skipInvalidate%28%29) –

ответ

0

Попробуйте это -

mWebView.scrollTo(...); 

webView.setDrawingCacheEnabled(true); 
webView.buildDrawingCache();//write these lines before posting the capture event 

new Handler.post(){ 
    new Runnable(){ 
     public void run(){ 
      final Bitmap bitmap = capture(mWebView); 
     } 
    } 
} 

Это может решить проблему ... :-)

+0

Спасибо за ответ, однако это не помогло. – foo

1

Я наконец-то нашел причину для этого. Мой механизм, который создал растровое изображение, основывался на том, что WebView имеет кэш чертежа и нарисован на моем холсте.

Кэш чертежа будет включен, но после изменения прокрутки он никогда не обновлялся, потому что изменилось только состояние представления.

Похоже, что, поскольку я разрешаю ускорение HW для рендеринга представления, все, что мне нужно сделать, это включить кеш чертежа и просто ПОЛЬЗОВАТЬ ЕГО всякий раз, когда мне нужно новое растровое изображение (мне даже не нужно аннулировать представление для цель) после установки положения прокрутки.

Таким образом, решение было бы что-то вроде:

public void init() { 
    mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
    mWebView.setDrawingCacheEnabled(true); 
    // (layout the view) 
} 

public void capture(...) { 
    mWebView.scrollTo(...); 
    final Bitmap capturedBitmap = mWebView.getDrawingCache(); 
    // do sth with the bitmap 
    // ... 
} 

Так что это все гораздо проще.

 Смежные вопросы

  • Нет связанных вопросов^_^