2015-05-13 2 views
5

Я использую платформу Android Print Framework для сохранения содержимого HTML в WebView в формате PDF. Поскольку WebView в Android-L имеет новый подход к рендерингу содержимого WebView, рекомендуется вызвать метод enableSlowWholeDocumentDraw() перед созданием веб-просмотров. Это отключит оптимизацию рендеринга, поэтому WebView сможет отображать всю HTML-страницу.Нарисуйте WebView на холсте в Android-L

Вот часть кода для рисования WebView на холсте.

PdfDocument.Page page = document.startPage(pageInfo); 
mWebView.draw(page.getCanvas()); 

Я пытался дозвониться WebView.enableSlowWholeDocumentDraw() из приложения, BaseActivity, а также сразу после и до создания WebView внутри моего фрагмента. Но это не помогло.

Я попытался включить/отключить аппаратное ускорение, установив тип слоя как ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ и ОБОРУДОВАНИЕ, но это тоже не помогло. Я все еще не могу рисовать весь WebView. На холст будет нарисована только видимая часть.

Кто-нибудь заметил это поведение? Есть ли решение для этого или это ошибка?

EDIT

Оказывается, что это не про WebView.enableSlowWholeDocumentDraw(), и мы все еще обсуждаем о проблеме. Это Bug Report. И вот Sample App, чтобы воспроизвести проблему.

ответ

2

Перед созданием необходимо позвонить WebViews в вашем приложении.

То есть, если у вас есть WebView где-то в вашем статическом макете, убедитесь, что вы звоните WebView.enableSlowWholeDocumentDraw() перед первым вызовом setContentView(), который раздувает макет с помощью WebView.

Также убедитесь, что ваш WebView действительно большой. Например, если его размер макета установлен на match_parent, то ваш WebView будет иметь размер экрана, и это то, что будет захвачено. Вам нужно установить некоторые искусственно высокие значения для ширины и высоты. Этот вопрос содержит хорошую иллюстрацию для этого: WebView.draw() not properly working on latest Android System WebView Update

+1

Как я указал в своем вопросе, я знаю об этом изменении в последней версии Android, и я назвал этот статический метод «WebView.enableSlowWholeDocumentDraw()» из onCreate of Application, перед setContentView в базовой операции и сразу после раздувания моего представления во фрагменте. Это не повлияло вообще – osayilgan

+0

Я вижу, извините за это. Тогда, вероятно, стоит дважды проверить, что ваш WebView действительно имеет большой размер, например. с [hierarchyviewer] (http://developer.android.com/tools/help/hierarchy-viewer.html). Кроме того, вы можете проверить, как работает ваше приложение в KitKat, где всегда был весь документ. –

+1

Я проверил его с KitKat, он работает так, как ожидалось. Таким образом, размер WebView должен быть хорошим. – osayilgan

3

Я являюсь автором this question.

Для решения этой проблемы мне пришлось позвонить WebView.enableSlowWholeDocumentDraw()до раздуть представление в вашем фрагменте. В комментариях ответа Михаила Наганова я увидел, что вы пробовали множество вариантов, но не этот. Ниже приведен код, который я использую в методе onCreateView() вашего фрагмента с помощью WebView.

public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle bundle){ 
    //Enable the drawing of the whole document for Lollipop to get the whole WebView 
    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){ 
     WebView.enableSlowWholeDocumentDraw(); 
    } 
    View view = inflater.inflate(R.layout.my_layout, parent, false); 

    /* Rest of code */ 
} 

В этом нет ничего другого. Если это не сработает, это может быть ошибка, и вы должны сообщить, как предложил Михаил.

Надеюсь, это поможет!

+1

Спасибо за ответ. Я попробовал эту альтернативу, а также назвал этот метод в onCreate и onAttach из Fragment. Ничто не работает. Я думаю, это может быть ошибка. Я создам билет и поделись ссылкой здесь. – osayilgan

+0

[ЗДЕСЬ] (https://code.google.com/p/chromium/issues/detail?id=490246) является ссылкой на мой отчет об ошибке – osayilgan

+1

Я создал простое приложение, чтобы показать, что оно не работает. Это может быть очень полезно, если вы можете взглянуть и сказать мне, есть ли что-то другое, чем вы. https://github.com/osayilgan/WebViewDemo – osayilgan

0
if(Build.VERSION.SDK_INT>=21) { 
    WebView.enableSlowWholeDocumentDraw(); 
} 

public void capture(WebView webView) { 
    WebView lObjWebView = webView; 
    lObjWebView.measure(MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 
    lObjWebView.layout(0, 0, lObjWebView.getMeasuredWidth(), lObjWebView.getMeasuredHeight()); 
    Bitmap bm = Bitmap.createBitmap(lObjWebView.getMeasuredWidth(), lObjWebView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); 

    Canvas bigcanvas = new Canvas(bm); 
    Paint paint = new Paint(); 
    int iHeight = bm.getHeight(); 
    bigcanvas.drawBitmap(bm, 0, iHeight, paint); 
    lObjWebView.draw(bigcanvas); 

    if (bm != null) { 
     try { 
      File dir = new File(Environment.getExternalStorageDirectory() + "/" + "folder"); 

      Calendar lObjCalendar = Calendar.getInstance(); 

      int hour = lObjCalendar.get(Calendar.HOUR); 
      int min = lObjCalendar.get(Calendar.MINUTE); 
      int sec = lObjCalendar.get(Calendar.SECOND); 
      int mili = lObjCalendar.get(Calendar.MILLISECOND); 
      int day = lObjCalendar.get(Calendar.DAY_OF_YEAR); 
      int month = lObjCalendar.get(Calendar.MONTH); 
      int year = lObjCalendar.get(Calendar.YEAR); 

      String realDate = "ERS_" + day + month + year + "_" + hour + min + sec + mili; 

      if (dir.exists()) { 
       OutputStream fOut = null; 
       File file = new File(dir, realDate + ".jpg"); 
       fOut = new FileOutputStream(file); 

       bm.compress(Bitmap.CompressFormat.PNG, 50, fOut); 
       fOut.flush(); 
       fOut.close(); 
       bm.recycle(); 
      } 
      else { 

       if (dir.mkdir()) { 
        OutputStream fOut = null; 
        File file = new File(dir, realDate + ".jpg"); 
        fOut = new FileOutputStream(file); 

        bm.compress(Bitmap.CompressFormat.PNG, 50, fOut); 
        fOut.flush(); 
        fOut.close(); 
        bm.recycle(); 
       } 
       else { 
        ProjectUtil.showToast(WebPayment.this, "Problem in saving webview in external storage"); 
       } 
      } 
     } 
     catch (FileNotFoundException e) { 
      ProjectUtil.showToast(WebPayment.this, "Problem in saving webview in external storage"); 
     } 
     catch (IOException e) { 
      ProjectUtil.showToast(WebPayment.this, "Problem in saving webview in external storage"); 
     } 
     catch (Exception e) { 
      ProjectUtil.showToast(WebPayment.this, "Problem in saving webview in external storage"); 
     } 
    } 
} 
+1

Вы прочитали вопрос или любые другие ответы? Или вы просто ищете «как рисовать веб-просмотр в андроиде» и скопировали/ввели первый ответ, который вы нашли? – osayilgan

+0

Вы можете попробовать мой дорогой друг, если вы получите этот ответ в любом месте, так как в соответствии с вами его копия вставлена ​​... Позволяет избежать этого .. Что здесь такое, я тоже столкнулся с той же проблемой .. и я получил решение, используя таким образом .. Таким образом, вы можете по крайней мере попробовать это. Я сохраняю скриншот всего веб-представления, вы можете сделать свою часть. Первые несколько строк capture() помогут решить вашу проблему. –

+0

Только решение, которое я нашел, печатает всю страницу. – Martha

3

Борясь с этой/аналогичной проблемой сам по себе. Наконец, нашли решение, по какой-то причине webView.draw(page.getCanvas()) отображает весь контент с помощью KitKat, но не с Lollipop (даже с enableSlowWholeDocumentDraw()).
Однако, используя (webView.capturePicture()).draw(page.getCanvas()) в сочетании с enableSlowWholeDocumentDraw(), он работает на Lollipop, хотя capturePicture() устарел.
Последним потенциально важным моментом является то, что обычно вы видите много вызовов на «onDraw», поскольку webView загружает свои данные, и я обнаружил, что с Lollipop мой снимок был сделан преждевременно (до того, как контент был полностью загружен - досадно даже onPageFinished() метод обратного вызова webViewClient не гарантирует этого!) - мое решение состояло в том, чтобы иметь собственный webView и в методе onDraw, добавьте это как FIRST LINE: if(this.getContentHeight() == 0) return; , т. Е. Не потрудитесь делать какой-либо чертеж, если только не будет определенного содержимого , Таким образом, вы никогда не должны получать пустой снимок страницы - хотя из вашего описания это звучит, как будто это может не повлиять на вас ....

+0

Спасибо за ответ. Я проверю его и вернусь к вам как можно скорее. – osayilgan

+0

Я проверил его, он работает в 4.4, но в API 5.0 и 5.1. Он сбой. Я могу получить это только от LogCat. 'Fatal signal 11 (SIGSEGV), код 1, ошибка addr 0x0 in tid 22023 (Thread-43812) ' Я предполагаю, что это проблема с памятью. – osayilgan

+0

Вы образец рабочего кода, который я могу дать ему попробовать и сравнить с моим? – osayilgan

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