更新:
- 时间:2017年4月20日10:32:32
关于302重定向的问题大家可以去看看
前言:
今天review项目中的代码想起来之前修改一个有关Webview和ScrollView冲突的bug:
- 1.因为Webview和ScrollView都用滑动事件,导致webview很难被滑动,即使被滑动了一点也非常不顺畅
- 2.解决滑动冲突问题后发现,如果webview嵌套的html中含有轮播图等还是有问题。
解决方案:
其实这两个问题属于同一类的问题,都是Webview和ScrollView滑动时产生的冲突
解决方法很简单:
public class ScrollWebView extends WebView{
private float startx;
private float starty;
private float offsetx;
private float offsety;
public ScrollWebView(Context context) {
super(context);
}
public ScrollWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
startx = event.getX();
starty = event.getY();
Log.e("MotionEvent", "webview按下");
break;
case MotionEvent.ACTION_MOVE:
Log.e("MotionEvent", "webview滑动");
offsetx = Math.abs(event.getX() - startx);
offsety = Math.abs(event.getY() - starty);
if (offsetx > offsety) {
getParent().requestDisallowInterceptTouchEvent(true);
Log.e("MotionEvent", "屏蔽了父控件");
} else {
getParent().requestDisallowInterceptTouchEvent(false);
Log.e("MotionEvent", "事件传递给父控件");
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
}复制代码
自定义一个WebView,重写onTouchEvent方法。判断当手指横向滑动的偏移量(offsetx)大于纵向滑动的偏移量(offsety)时屏蔽父控件的滑动。
解决方法很简单,只要我们在遇到问题的时候多多思考,弄清楚错误的原因,有针对性的研究,绝大数的问题都是可以解决的。
webview使用总结
本来写到这里就想结束了,但是发现写的东西太少了,估计会被骂,既然写的是webview,索性就把我对webview的使用总结整理一下。
数据加载
- 加载本地资源
webView.loadUrl("file:///android_asset/text.html");复制代码
- 加载网络资源
webView.loadUrl("www.xxx.com/text.html");复制代码
- 添加请求头信息
Map<String,String> map=new HashMap<String,String>();
map.put("User-Agent","Android");
webView.loadUrl("www.xxx.com/text.html",map);复制代码
- 直接加载html代码片段
String html = "数据";
webView.loadDataWithBaseURL(null,html, "text/html", "utf-8",null);复制代码
支持JavaScript
- 设置支持JavaScript
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);//设置支持javascript
webView.addJavascriptInterface(new JavaScriptInterface(), "tyk");//添加一个对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法 复制代码
- JavaScriptInterface 接口定义
private final class JavaScriptInterface {
//JavaScript调用此方法拨打电话
public void call(String phone) {
//startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone)));
Toast.makeText(MainActivity.this, phone, Toast.LENGTH_LONG).show();
}
//Html调用此方法传递数据
public void showcontacts() {
String json = "[{\"name\":\"tyk\", \"amount\":\"9999999\", \"phone\":\"1831041486.\"}]";
// 调用JS中的方法
webView.loadUrl("javascript:show('" + json + "')");
}
} 复制代码
WebViewClient
- 主要辅助WebView处理各种通知、请求事件
onLoadResource//加载资源时响应
onPageStart//在加载页面时响应
onPageFinish//在加载页面结束时响应
onReceiveError//在加载出错时响应
onReceivedHttpAuthRequest//获取返回信息授权请求复制代码
- 要实现WebView中链接在WebView内部跳转
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});复制代码
WebChromeClient
- 主要辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等
onCloseWindow//关闭WebView
onCreateWindow() //触发创建一个新的窗口
onJsAlert //触发弹出一个对话框
onJsPrompt //触发弹出一个提示
onJsConfirm//触发弹出确认提示
onProgressChanged //加载进度
onReceivedIcon //获取网页icon
onReceivedTitle//获取网页title复制代码
- 加载进度获取title
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
//网页加载完成
} else {
//网页加载中
}
}
});复制代码
WebView 缓存控制
LOAD_CACHE_ONLY//不使用网络,只读取本地缓存数据
LOAD_DEFAULT//根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL//API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE//不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK//只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。复制代码
一般都是根据网络来判断缓存使用情况
//加载缓存形式
if (CommonUtils.getNetWorkStatus(context)){//判断网络是否可用
// 根据cache-control决定是否从网络上取数据。
websettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
}else{
// 只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
websettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}复制代码
页面返回
- 我们有时需要实现回退到上一目录
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webView.canGoBack()) {
webView.goBack();//返回上一浏览页面
return true;
} else {
finish();//关闭Activity
}
}
return super.onKeyDown(keyCode, event);
}复制代码
其他设置
WebSettings webSettings = webView.getSettings();
//支持缩放
webSettings.setSupportZoom(true);
//支持内容重新布局
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
//多窗口
webSettings.supportMultipleWindows();
//当webview调用requestFocus时为webview设置节点
webSettings.setNeedInitialFocus(true);
//设置支持缩放
webSettings.setBuiltInZoomControls(true);
//支持通过JS打开新窗口
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//支持自动加载图片
webSettings.setLoadsImagesAutomatically(true);
//提高渲染的优先级
websettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
// 开启H5(APPCache)缓存功能
websettings.setAppCacheEnabled(true);
// 开启 DOM storage 功能
websettings.setDomStorageEnabled(true);
// 应用可以有数据库
websettings.setDatabaseEnabled(true);
// 可以读取文件缓存(manifest生效)
websettings.setAllowFileAccess(true);复制代码