Android Webview和ScrollView衝突和WebView使用總結

更新:

前言:

今天review項目中的代碼想起來以前修改一個有關Webview和ScrollView衝突的bug:javascript

  • 1.由於Webview和ScrollView都用滑動事件,致使webview很難被滑動,即便被滑動了一點也很是不暢
  • 2.解決滑動衝突問題後發現,若是webview嵌套的html中含有輪播圖等仍是有問題。

解決方案:

其實這兩個問題屬於同一類的問題,都是Webview和ScrollView滑動時產生的衝突 解決方法很簡單:html

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)時屏蔽父控件的滑動。 解決方法很簡單,只要咱們在遇到問題的時候多多思考,弄清楚錯誤的緣由,有針對性的研究,絕大數的問題都是能夠解決的。java

webview使用總結

原本寫到這裏就想結束了,可是發現寫的東西太少了,估計會被罵,既然寫的是webview,索性就把我對webview的使用總結整理一下。android

數據加載

  • 加載本地資源 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中的方法web

  • 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//獲取返回信息受權請求json

  • 要實現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網絡

  • 加載進度獲取titleide

    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);
複製代碼
相關文章
相關標籤/搜索