| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
rlbx7836
7年前发布

Android Webview 和 ScrollView 冲突和 WebView 使用总结

   <h3>前言:</h3>    <p>今天review项目中的代码想起来之前修改一个有关Webview和ScrollView冲突的bug:</p>    <ul>     <li>1.因为Webview和ScrollView都用滑动事件,导致webview很难被滑动,即使被滑动了一点也非常不顺畅</li>     <li>2.解决滑动冲突问题后发现,如果webview嵌套的html中含有轮播图等还是有问题。</li>    </ul>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6581bd3d2c018bc93caa5fee48e4973e.gif"></p>    <h3>解决方案:</h3>    <p>其实这两个问题属于同一类的问题,都是Webview和ScrollView滑动时产生的冲突</p>    <p>解决方法很简单:</p>    <pre>  <code class="language-java">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);      }  }</code></pre>    <p>自定义一个WebView,重写onTouchEvent方法。判断当手指横向滑动的偏移量(offsetx)大于纵向滑动的偏移量(offsety)时屏蔽父控件的滑动。</p>    <p>解决方法很简单,只要我们在遇到问题的时候多多思考,弄清楚错误的原因,有针对性的研究,绝大数的问题都是可以解决的。</p>    <h2>webview使用总结</h2>    <p>本来写到这里就想结束了,但是发现写的东西太少了,估计会被骂,既然写的是webview,索性就把我对webview的使用总结整理一下。</p>    <h3>数据加载</h3>    <ul>     <li>加载本地资源 <pre>  <code class="language-java">webView.loadUrl("file:///android_asset/text.html");</code></pre> </li>     <li>加载网络资源 <pre>  <code class="language-java">webView.loadUrl("www.xxx.com/text.html");</code></pre> </li>     <li>添加请求头信息 <pre>  <code class="language-java">Map<String,String> map=new HashMap<String,String>();    map.put("User-Agent","Android");    webView.loadUrl("www.xxx.com/text.html",map);</code></pre> </li>     <li>直接加载html代码片段 <pre>  <code class="language-java">String html = "数据";    webView.loadDataWithBaseURL(null,html, "text/html", "utf-8",null);</code></pre> </li>    </ul>    <h3>支持JavaScript</h3>    <ul>     <li>设置支持JavaScript <pre>  <code class="language-java">WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);//设置支持javascript    webView.addJavascriptInterface(new JavaScriptInterface(), "tyk");//添加一个对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法  </code></pre> </li>    </ul>    <ul>     <li> <p>JavaScriptInterface 接口定义</p> <pre>  <code class="language-java">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 + "')");          }      }</code></pre> </li>    </ul>    <h3>WebViewClient</h3>    <ul>     <li> <p>主要辅助WebView处理各种通知、请求事件</p> <pre>  <code class="language-java">onLoadResource//加载资源时响应    onPageStart//在加载页面时响应    onPageFinish//在加载页面结束时响应    onReceiveError//在加载出错时响应    onReceivedHttpAuthRequest//获取返回信息授权请求</code></pre> </li>     <li> <p>要实现WebView中链接在WebView内部跳转</p> <pre>  <code class="language-java">webView.setWebViewClient(new WebViewClient() {        public boolean shouldOverrideUrlLoading(WebView view, String url) {            view.loadUrl(url);            return true;        }    });</code></pre> </li>    </ul>    <h3>WebChromeClient</h3>    <ul>     <li> <p>主要辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等</p> <pre>  <code class="language-java">        onCloseWindow//关闭WebView            onCreateWindow() //触发创建一个新的窗口            onJsAlert //触发弹出一个对话框            onJsPrompt //触发弹出一个提示            onJsConfirm//触发弹出确认提示            onProgressChanged //加载进度            onReceivedIcon //获取网页icon            onReceivedTitle//获取网页title</code></pre> </li>     <li> <p>加载进度获取title</p> <pre>  <code class="language-java">webView.setWebChromeClient(new WebChromeClient() {        @Override        public void onProgressChanged(WebView view, int newProgress) {            if (newProgress == 100) {                //网页加载完成            } else {                //网页加载中            }        }    });</code></pre> </li>    </ul>    <h3>WebView 缓存控制</h3>    <pre>  <code class="language-java">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,都使用缓存中的数据。</code></pre>    <p>一般都是根据网络来判断缓存使用情况</p>    <pre>  <code class="language-java">//加载缓存形式          if (CommonUtils.getNetWorkStatus(context)){//判断网络是否可用              // 根据cache-control决定是否从网络上取数据。              websettings.setCacheMode(WebSettings.LOAD_NO_CACHE);          }else{              // 只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。              websettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);          }</code></pre>    <h3>页面返回</h3>    <ul>     <li> <p>我们有时需要实现回退到上一目录</p> <pre>  <code class="language-java">@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);    }</code></pre> </li>    </ul>    <h3>其他设置</h3>    <pre>  <code class="language-java">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);</code></pre>    <p> </p>    <p>来自:https://juejin.im/post/58f714ac570c35005651a347</p>    <p> </p>    
 本文由用户 rlbx7836 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1492654812234.html
Android开发 移动开发 ScrollView