Android Webview: обнаружение при завершении рендеринга
Я хочу сделать снимок WebView после загрузки WebView. Однако возвращаемое растровое изображение всегда равно нулю, поскольку рендеринг не загружен, даже если я использую onPageFinished
.
Я ищу в Интернете, и люди предлагают использовать WebView.PictureListener
, но эта функция устарела в API 12.
Некоторые коды
public class MainActivity extends Activity {
private WebView mButterflyWebView;
/**
* Gets html content from the assets folder.
*/
private String getHtmlFromAsset() {
InputStream is;
StringBuilder builder = new StringBuilder();
String htmlString = null;
try {
is = getAssets().open(getString(R.string.butterfly_html));
if (is != null) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
htmlString = builder.toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return htmlString;
}
/**
* Initializes views, controls...
*/
private void init() {
mButterflyWebView = (WebView) findViewById(R.id.butterfly_webview);
mButterflyWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100){
if (capturePictureWebView() != null){
saveBitmapToFile(capturePictureWebView());
}
}
}
});
}
/**
* Loads html page with the content.
*/
private void loadHtmlPage() {
String htmlString = getHtmlFromAsset();
if (htmlString != null)
mButterflyWebView.loadDataWithBaseURL(
"file:///android_asset/images/", htmlString, "text/html",
"UTF-8", null);
else
Toast.makeText(this, R.string.no_such_page, Toast.LENGTH_LONG)
.show();
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
loadHtmlPage();
}
private Bitmap capturePictureWebView() {
mButterflyWebView.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mButterflyWebView.layout(0, 0, mButterflyWebView.getMeasuredWidth(),
mButterflyWebView.getMeasuredHeight());
mButterflyWebView.setDrawingCacheEnabled(true);
mButterflyWebView.buildDrawingCache();
if (mButterflyWebView.getMeasuredWidth() == 0 || mButterflyWebView.getMeasuredHeight() == 0){
return null;
}
Bitmap bm = Bitmap.createBitmap(720, 1280, Bitmap.Config.ARGB_8888);
System.out.println("width=" + mButterflyWebView.getMeasuredWidth());
System.out.println("height=" + mButterflyWebView.getMeasuredHeight());
Canvas bigcanvas = new Canvas(bm);
// bigcanvas.scale(720/mButterflyWebView.getMeasuredWidth(), 1280/mButterflyWebView.getMeasuredHeight());
Paint paint = new Paint();
int iHeight = bm.getHeight();
bigcanvas.drawBitmap(bm, 0, iHeight, paint);
mButterflyWebView.draw(bigcanvas);
return bm;
}
private void saveBitmapToFile(Bitmap bitmap) {
try {
FileOutputStream out = new FileOutputStream("/storage/sdcard0/a.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Ответы
Ответ 1
Наконец, я получил очень подробную информацию по этой проблеме. Это объясняет, почему он всегда возвращает нулевой битмап.
Каждое изменение в моем приложении запускается с помощью действия пользователя, поэтому я придумал модифицированную версию, которая вызывает только invalidate() после touchEvent
Спасибо за вашу помощь.
Android WebView отображает пустой/белый, просмотр не обновляется при изменениях css или изменениях в HTML, анимации изменчивы
Ответ 2
Вам следует попробовать использовать WebChromeClient
и реализовать onProgressChanged
:
http://developer.android.com/reference/android/webkit/WebChromeClient.html#onProgressChanged(android.webkit.WebView, int)
mButterflyWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int progress) {
if (progress == 100) {
// do screenshot
}
}
});
EDIT: чтобы проверить, загружен ли onPageStarted более одного раза:
mButterflyWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d("WebView", "onPageStarted " + url);
}
@Override
public void onPageFinished(WebView view, String url) {
Log.d("WebView", "onPageFinished " + url);
}
});
Ответ 3
Вы можете сделать это в своем WebView:
@Override
public void invalidate() {
super.invalidate();
if (getContentHeight() > 0) {
// WebView has displayed some content and is scrollable.
}
}
Благодаря: fooobar.com/questions/142082/...
Ответ 4
Лучший способ определить, была ли отображаемая страница, - использовать обратный вызов onPageCommitVisible, доступный из API 23. onPageLoadFinished
не подходит, так как он отправлен слишком рано (когда HTML обрабатывается, но еще не отображается).
webview.setWebViewClient(новый WebViewClient() {
@Override
public void onPageCommitVisible (WebView view,
String url)
}
}
Ответ 5
private class CfdWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.v(TAG, "shouldOverrideUrlLoading: " + url);;
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.v(TAG, "onPageFinished: " + url);
// do something
}
}