2015-05-13 7 views
5

Ich verwende Android Print Framework, um den HTML-Inhalt des WebView als PDF zu speichern. Da WebView in Android-L einen neuen Ansatz zum Rendern des WebView-Inhalts bietet, wird empfohlen, vor dem Erstellen von Webansichten die Methode enableSlowWholeDocumentDraw() aufzurufen. Dadurch wird die Rendering-Optimierung deaktiviert, sodass WebView die gesamte HTML-Seite rendern kann.Zeichnen Sie WebView in ein Canvas in Android-L

Hier ist der Teil des Codes zum Zeichnen von WebView in einen Canvas.

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

Ich versuchte WebView.enableSlowWholeDocumentDraw() aus Anwendung, BaseActivity Aufruf und auch direkt vor und nach WebView in meinem Fragmente erstellen. Aber das hat nicht geholfen.

Ich habe versucht, die Hardware-Beschleunigung zu aktivieren/deaktivieren, indem ich den Layer-Typ als SOFTWARE und HARDWARE einstelle, aber das half auch nicht. Ich kann immer noch nicht den gesamten WebView zeichnen. Nur der sichtbare Teil wird in den Canvas gezeichnet.

Hat jemand dieses Verhalten bemerkt? Gibt es dafür eine Lösung oder ist das ein Bug?

EDIT

Es stellt sich heraus, dass es nicht über WebView.enableSlowWholeDocumentDraw() ist und wir diskutieren noch über das Thema. Dies ist die Bug Report. Und hier ist die Sample App, um das Problem zu reproduzieren.

Antwort

2

Sie müssen WebView.enableSlowWholeDocumentDraw() anrufen, bevor Sie beliebige WebViews in Ihrer App erstellen.

Das heißt, wenn Sie ein WebView irgendwo in Ihrem statischen Layout haben, stellen Sie sicher, dass Sie WebView.enableSlowWholeDocumentDraw() vor Ihrem ersten Anruf an setContentView() aufrufen, der ein Layout mit WebView aufbläht.

Stellen Sie außerdem sicher, dass Ihr WebView tatsächlich groß ist. Beispiel: Wenn die Layoutgröße auf eingestellt ist, hat Ihr WebView die Größe des Bildschirms, und dies wird erfasst. Sie müssen einige künstlich hohe Werte für Breite und Höhe einstellen. Diese Frage enthält eine schöne Illustration dafür: WebView.draw() not properly working on latest Android System WebView Update

+1

Wie ich in meiner Frage angedeutet habe, bin ich mir dieser Änderung in der bewusst neueste Android-Version, und ich habe diese statische "WebView.SensableWlowDocumentDraw()" -Methode von onCreate der Anwendung, vor setContentView in der Basis-Aktivität und direkt nach dem Aufblasen meiner Ansicht in Fragment aufgerufen. Es hat überhaupt keinen Effekt – osayilgan

+0

Ich sehe, Entschuldigung dafür. Dann ist es wahrscheinlich eine Überprüfung wert, dass Ihr WebView tatsächlich eine große Größe hat, z. with [hierarchyviewer] (http://developer.android.com/tools/help/hierarchy-viewer.html) Sie können auch überprüfen, wie sich Ihre Anwendung auf KitKat verhält, wo immer das gesamte Dokument gerendert wurde. –

+1

Ich habe es mit KitKat überprüft, es funktioniert wie erwartet. Also sollte die WebView-Größe auch in Ordnung sein. – osayilgan

3

Ich bin der Autor von this question.

Um dieses Problem zu beheben, musste ich WebView.enableSlowWholeDocumentDraw()vor aufrufen, um die Ansicht in Ihrem Fragment aufzublasen. In den Kommentaren von Mikhail Naganovs Antwort habe ich gesehen, dass Sie viele Optionen ausprobiert haben, aber nicht diese. Unten ist der Code, den ich in der onCreateView() Methode Ihres Fragments mit dem WebView verwende.

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 */ 
} 

Da ist wirklich nichts anderes. Wenn das nicht funktioniert, dann könnte es ein Fehler sein und Sie sollten sich melden, wie Mikhail vorgeschlagen hatte.

Hoffe, das hilft!

+1

Danke für die Antwort. Ich habe diese Alternative versucht und diese Methode in onCreate und onAttach des Fragments aufgerufen. Nichts scheint zu funktionieren. Ich denke, es könnte ein Fehler sein. Ich werde ein Ticket erstellen und den Link hier teilen. – osayilgan

+0

[HIER] (https://code.google.com/p/chromium/issues/detail?id=490246) ist ein Link zu meinem Fehlerbericht – osayilgan

+1

Ich habe eine einfache Anwendung erstellt, um zu zeigen, dass sie nicht funktioniert. Es könnte wirklich hilfreich sein, wenn du einen Blick darauf werfen kannst und mir sagst, ob es etwas anderes als dich gibt. 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

Haben Sie die Frage oder andere gegebene Antworten gelesen? Oder du suchst einfach nach "how to remove webview in android" und kopierst/klebst die erste Antwort, die du gefunden hast? – osayilgan

+0

Sie können versuchen, mein lieber Freund, wenn Sie diese Antwort überall erhalten, wie Sie Ihre Kopie eingefügt ... Lässt vermeiden, dass .. Was imp hier ist .. Ich war auch mit dem gleichen Problem .. und ich habe die Lösung mit auf diese Weise .. So können Sie atleast dies versuchen .. Ich spare Screenshot der gesamten Web-Ansicht, können Sie Ihren Teil .. Die ersten paar Zeilen der Erfassung() wird Ihr Problem lösen. –

+0

Einzige Lösung, die ich gefunden habe, druckt die gesamte Seite. – Martha

3

Bekam mit diesem/ähnlichen Problem mich seit Ewigkeiten. Schließlich eine Lösung gefunden, aus irgendeinem Grund webView.draw(page.getCanvas()) macht den gesamten Inhalt mit KitKat aber nicht mit Lollipop (auch mit enableSlowWholeDocumentDraw()).
Die Verwendung von (webView.capturePicture()).draw(page.getCanvas()) in Kombination mit enableSlowWholeDocumentDraw() funktioniert jedoch für Lollipop, obwohl capturePicture() veraltet ist.
Ein letzter potentiell wichtiger Punkt ist, dass normalerweise viele Aufrufe von "onDraw" angezeigt werden, während ein WebView seine Daten lädt und ich feststelle, dass mit Lollipop mein Snapshot vorzeitig genommen wurde (bevor der Inhalt vollständig geladen wurde - nervend sogar die onPageFinished() Callback-Methode von WebViewClient garantiert dies nicht!) - Meine Lösung war eine benutzerdefinierte WebView und in der OnDraw-Methode, fügen Sie diese als die erste Zeile: if(this.getContentHeight() == 0) return; dh keine Mühe, um eine Zeichnung zu machen, wenn es einige richtige Inhalt ist . Auf diese Weise sollten Sie nie einen leeren Seitenschnappschuss bekommen - obwohl es aus Ihrer Beschreibung klingt, dass dies keinen Einfluss auf Sie hat.

+0

Danke für die Antwort. Ich werde es testen und so schnell wie möglich zu dir zurückkommen. – osayilgan

+0

Ich habe es überprüft, es funktioniert in 4.4, aber in API 5.0 und 5.1 stürzt es ab. Ich konnte das nur von LogCat bekommen. 'Fatales Signal 11 (SIGSEGV), Code 1, Fehleradresse 0x0 in tid 22023 (Thread-43812) ' Ich nehme an, es ist ein Speicherproblem. – osayilgan

+0

Haben Sie ein funktionierendes Codebeispiel, das ich ausprobieren und mit meinem vergleichen kann? – osayilgan