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

rlbx7836 7年前發布 | 16K 次閱讀 Android開發 移動開發 ScrollView

前言:

今天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);
}

}</code></pre>

自定義一個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 + "')");  
      }  
    

    }</code></pre> </li> </ul>

    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);

     

    來自:https://juejin.im/post/58f714ac570c35005651a347

     

 本文由用戶 rlbx7836 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!