知识的领域是无限的,我们的学习也是无限期的。这篇文章主要讲述Android WebView学习相关的知识,希望能为你提供帮助。
android WebView学习
文章来源:小小懒羊羊个人知识管理库权限:<
uses-permission android:name=“android.permission.INTERNET”
/>
在WebView中使用javascriptWebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setjavaScriptEnabled(true);
绑定JavaScript代码到Android源代码
public class JavaScriptInterface { Context mContext; /** Instantiate the interface and set the context */ JavaScriptInterface(Context c) { mContext = c; } /** Show a toast from the web page */ public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } } WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
这段代码会创建一个名称为“Android”的JavaScript接口并执行在WebView其中。在这里。你的Web应用会接入到JavaScriptInterface类。比如,以下为html何JavaScript代码,它会在用户点击button的时候使用新的接口创建一个Toast消息。
< input type="button" value="https://www.songbingjia.com/android/Say hello" onClick="Android.showToast(\'Hello Android!\')" />
备注:在JavaScript中绑定的对象会执行在还有一个线程,它和创建它的线程是不同的线程。
处理页面导航
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
完毕,如今用户点击的全部链接都会在WebView中打开。假设你想要在点击链接并加载网页的时候做很多其它的操作,请创建自己的WebViewClient 并重写java.lang.String) shouldOverrideUrlLoading()方法。比如:
private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (Uri.parse(url).getHost().equals("www.example.com")) { //这是我的网页,所以不要重写,让我的WebView加载它 return false; } // 假设不是我的网页,则启动另外的Activity来处理该URL Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); return true; } }
操作网页历史当你的WebView重写URL的加载。它会自己主动累积訪问过的网页历史。你能够使用
goBack()方法和goForward()
方法操纵回退和向前功能。
比如,以下是Activity使用返回button操作“回退”功能@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check if the key event was the Back button and if there\'s history if ((keyCode == KeyEvent.KEYCODE_BACK) & & myWebView.canGoBack() { myWebView.goBack(); return true; } // If it wasn\'t the Back key or there\'s no web page history, bubble up to the default // system behavior (probably exit the activity) return super.onKeyDown(keyCode, event); }
fragment中webview的历史操作
webview.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (keyCode == KeyEvent.KEYCODE_BACK & & webview.canGoBack()) {//表示按返回键 时的操作 webview.goBack(); //后退 return true; //已处理 } } return false; } });
webview.loaddata乱码解决loadData()中的html data中不能包括\'#\', \'%\', \'\\\', \'?
\'四中特殊字符。出现这样的字符就会出现解析错误,显示找不到网页还有部分html代码。须要怎样处理呢?我们须要用UrlEncoder编码为%23, %25, %27, %3f 。
能够使用下面两种代码,data为string类型的html代码
1、webView.loadData(URLEncoder.encode(data, “utf-8”), “text/html”, “utf-8”); 这样一些背景效果什么的都不怎么好看了。不推荐。
2、webView.loadDataWithBaseURL(null,data, “text/html”, “utf-8”, null);
这样就会完美解析了。
编辑
webview中文乱码解决:
方式一: //webView.loadData(htmlData, "text/html", "UTF-8"); //API提供的标准使用方法。无法解决乱码问题 webView.loadData(htmlData, "text/html; charset=UTF-8", null); //这样的写法能够正确解码 方式二 //先调用这句然后再载入数据 webView.getSettings().setDefaultTextEncodingName("UTF-8"); //设置默觉得utf-8 webView.loadData(htmlData, "text/html; charset=UTF-8", null); //这样的写法能够正确解码 方式三:推荐 webView.getSettings().setDefaultTextEncodingName("UTF-8"); //设置默觉得utf-8 webView.loadDataWithBaseURL(null,data, "text/html","utf-8", null);
WebView不载入图片问题loadData不能载入图片内容,假设要载入图片内容或者获得更强大的Web支持请使用
loadDataWithBaseURL
。android_webview中内容获取在程序中常常会用到webView来显示网页,但假设可以得到网页中的内容呢
//定义java的js交互接口,这个类将会被js操纵。 class WebViewContent{ @JavascriptInterface public void getContent(String data){ webViewContent=data; } } //定义WebView并开启、绑定与JS的交互,以便获取webview中的html内容。
WebSettings settings = webView.getSettings(); //开启缩放支持 settings.setSupportZoom(true); settings.setBuiltInZoomControls(true); //启用JS settings.setJavaScriptEnabled(true); //默认对缩放比例有限制。导致用户体验不好。所以须要设置为使用随意比例缩放。
settings.setUseWideViewPort(true); //使页面之间能够点击链接导航 webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient()); //初始页面一般过大。我们设置为75% //webView.setInitialScale(75); //设置默觉得utf-8,否则会出现乱码现象 webView.getSettings().setDefaultTextEncodingName("UTF -8"); //使用loadDataWithBaseURL替代loadData以提供更好的体验和防止乱码。 webView.loadDataWithBaseURL(null, model.getSummary(), "text/html", "UTF-8", null); //将JS接口类WebViewContent进行绑定,绑定到js中的handler对象 webView.addJavascriptInterface(new WebViewContent(),"handler"); //通过WebViewClient操作。
webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { //页面载入完毕获取内容,通过js代码就可以获取数据到绑定的js接口对象的相应方法中。 view.loadUrl("javascript:window.handler.getContent(\'< html> \'+document.getElementsByTagName(\'html\')[0].innerHTML+\'< /html> \'); "); super.onPageFinished(view, url); } });
Android 中Webview 自适应屏幕方式一:在HTML页面中使用Viewport Metadata
< head> < title> Example< /title> < meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> < /head>
上文仅仅是一个仅仅有两个viewport属性样例,下文描写叙述了全部支持的viewport属性及其同意的值类型。
< meta name="viewport" content=" height = [pixel_value | device-height] , width = [pixel_value | device-width ] , initial-scale = float_value , minimum-scale = float_value , maximum-scale = float_value , user-scalable = [yes | no] , target-densitydpi = [dpi_value | device-dpi | high-dpi | medium-dpi | low-dpi] " />
自己主动调整尺寸
<
meta name=“viewport” content=“width=device-width”
/>
提前定义viewport缩放viewport的缩放值定义了页面所同意的缩放范围。
viewport属性同意您通过下面方式指定您的页面缩放:
initial-scale
页面的初始缩放。这个值是一个指示您的页面相对于屏幕大小倍数的float值。比如,假设您设置初始缩放为“1.0”那么页面将依据目标密度1比1的显示。假设设置为“2.0”那么页面将放大2倍。
为了将网页与viewport尺寸匹配,默认初始缩放是计算过的。
由于默认viewport 是800像素宽。假设设备屏幕推断为小于800像素宽,初始缩放将以小于1.0的某个值为默认值,以便在屏幕上匹配一个800像素宽的页面。
minimum-scale
同意的最小缩放。这个值是一个指示您的页面相对于屏幕大小最小倍数的float值。比如,假设您设置为1.0。那么由于最小大小和目标密度是1:1的,页面就不能缩小。
maximum-scale
同意的最大缩放。这个值是一个指示您的页面相对于屏幕大小最大倍数的float值。比如您设置此值为2.0,那么您就不能放大超过2倍。
user-scalable
是否同意用户缩放此页面。
设置为yes同意缩放,no为不同意缩放。默认值是yes。假设您设置此值为no,那么minimum-scale和maximum-scale将会被忽略。由于缩放不可用。
所以的缩放值必须在0.01到10之间。
<
meta name=“viewport” content=“initial-scale=1.0” />
这个metadata设置初始缩放为相对于viewport目标密度的原始大小。
提前定义viewport匹配密度设备屏幕的密度基于屏幕决定。由每英寸的像素数(dpi)定义。有三种Android支持的密度:高(hdpi)、中(mdpi)和低(ldpi)
您能够通过使用viewport属性target-densitydpi来为您的网页改变目标密度。它同意下面的值:
device-dpi - 使用设备本地的dpi作为目标dpi。默认缩放将不会起作用。
high-dpi - 使用hdpi作为目标dpi。 中和低密度的屏幕将会适当缩小。
.
medium-dpi - 使用mdpi作为目标dpi。
高和低密度的屏幕将会分别放大和缩小。这是默认的密度值。
low-dpi - 使用ldpi作为目标dpi。 中和高密度的屏幕将会适当放大。
< value> - 指定一个dpi值作为目标dpi。该值必须在70-400之间。
比如,您能够通过设置viewport的target-densitydpi属性,来阻止Android浏览器和WebView为不同的分辨率缩放网页。而这个页面会以当匹配前屏幕的密度的大小显示。
在本例中,您相同应该定义viewport的宽以匹配设备宽度。这样您的页面才会自然适合屏幕大小。比如:
<
meta name=“viewport” content=“target-densitydpi=device-dpi, width=device-width”
/>
方式二:用JavaScript适配设备密度
Android浏览器和WebView支持同意您请求当前设备的屏幕密度的DOM属性 - DOM属性 window.devicePixelRatio。这个属性的值 指定当前设备使用的比例系数。比如,假设window.devicePixelRatio的值是“1.0”。那么这个设备被觉得是中等密度而且默认情况下不缩放;假设这个值是“1.5”,那么这个设备被觉得是高密度而且默认情况下放大1.5x。假设这个值是“0.75”。那么这个设备被觉得是低密度而且默认情况下缩小0.75x。默认匹配的是中等密度,可是您能够改变这个密度匹配来改变不同屏幕密度下您网页的缩放。
if (window.devicePixelRatio == 1.5) { alert("This is a high-density screen"); } else if (window.devicePixelRatio == 0.75) { alert("This is a low-density screen"); }
方式三:使用代码方式
本人測试还是存在问题
关键代码:
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
WebSettings settings = webView.getSettings(); settings.setSupportZoom(true); //开启缩放支持 settings.setBuiltInZoomControls(true); //开启缩放支持 settings.setJavaScriptEnabled(true); settings.setDisplayZoomControls(false); //隐藏webview缩放button //默认对缩放比例有限制。导致用户体验不好。所以须要设置为使用随意比例缩放。 settings.setUseWideViewPort(true); //设置webView自适应手机屏幕 settings.setLoadWithOverviewMode(true); settings.setDefaultTextEncodingName("UTF -8"); //设置默觉得utf-8 //使页面之间能够点击链接导航 webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient());
參考:http://www.cnblogs.com/bluestorm/archive/2013/04/15/3021996.html
方式四:综合方式-强烈推荐
參考:http://www.cppblog.com/WhiteDummy/archive/2013/06/25/201300.aspx
假设想要得到正常的倍率,是须要配合网页端的。
(这里仅讨论html5的场合,跨平台嘛)
个人觉得,由网页方面写死一个宽,再提供一个js的缩放函数(包含图片。字体),依据不同设备的分辨率来调用,是比較理想的。(当然,也能够用穷举法,一个分辨率进一个网页。用不同css和不同大小资源 =_=!)
如果宽定位1280,则html5方面必须有:
<
meta name=“viewport” content=“width=1280, initial-scale=1.0,maximum-scale=2.0, minimum-scale=0.5,
user-scalable=no,target-densitydpi=device-dpi” />
当中,target-densitydpi是最重要的,它将配合android端的下面代码使用。
//use html5 viewport attribute settings.setLoadWithOverviewMode(true); settings.setUseWideViewPort(true);
表示我们的代码支持html5网页自适应。所谓杀什么畜生用什么刀。网页的事情。dpi适应什么的,就交给html5去做好了 = =。不用我们在更外面一层蛋疼。
这样做之后。1280宽的图片不管在什么设备的分辨率都是正常的尺寸,不会被做倍数不明的拉伸,方便我们控制。
【Android WebView学习】最后我採取的策略:
<
meta name=“viewport” content=“width=device-width, initial-scale=1.0, user-scalable=yes,target-densitydpi=device-dpi”>
//use html5 viewport attribute settings.setLoadWithOverviewMode推荐阅读
- Android Material Design--TextInputLayout
- I.MX6 Android 设备节点权限
- 使用Android Studio自带的NDK编译JNI
- Atitit orm的实现模式data-mapper模式和active-record模式有什么区别
- You never know what's going to happen
- Android system (灯光系统_HAL_lights)
- Android[Problem]-"Waiting for target device to come online".
- Android system ( Led class 节点添加)
- android launcher2开发之有抽屉改成无抽屉