1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| /** * ================================================ * 作 者:杨充 * 版 本:1.0 * 创建日期:2017/3/28 * 描 述:实现WebView的滑动监听和优雅处理回退栈问题 * 修订历史: * ================================================ */ public class ScrollWebView extends WebView {
private boolean mTouchByUser; 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); }
public OnScrollWebListener getOnScrollWebListener() { return onScrollWebListener; }
private OnScrollWebListener onScrollWebListener; public void setScrollWebListener(OnScrollWebListener onScrollWebListener) { this.onScrollWebListener = onScrollWebListener; }
public interface OnScrollWebListener { void onScroll(int dx, int dy); }
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (onScrollWebListener != null) { onScrollWebListener.onScroll(l - oldl, t - oldt); } }
@Override public final void loadUrl(String url, Map<String, String> additionalHttpHeaders) { super.loadUrl(url, additionalHttpHeaders); resetAllStateInternal(url); }
@Override public void loadUrl(String url) { super.loadUrl(url); resetAllStateInternal(url); }
@Override public final void postUrl(String url, byte[] postData) { super.postUrl(url, postData); resetAllStateInternal(url); }
@Override public final void loadData(String data, String mimeType, String encoding) { super.loadData(data, mimeType, encoding); resetAllStateInternal(getUrl()); }
@Override public final void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) { super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); resetAllStateInternal(getUrl()); }
@Override public void reload() { super.reload(); resetAllStateInternal(getUrl()); }
public boolean isTouchByUser() { return mTouchByUser; }
private void resetAllStateInternal(String url) { if (!TextUtils.isEmpty(url) && url.startsWith("javascript:")) { return; } resetAllState(); }
// 加载url时重置touch状态 protected void resetAllState() { mTouchByUser = false; }
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //用户按下到下一个链接加载之前,置为true mTouchByUser = true; break; } return super.onTouchEvent(event); }
@Override public void setWebViewClient(final WebViewClient client) { super.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { boolean handleByChild = null != client && client.shouldOverrideUrlLoading(view, url); if (handleByChild) { // 开放client接口给上层业务调用,如果返回true,表示业务已处理。 return true; } else if (!isTouchByUser()) { // 如果业务没有处理,并且在加载过程中用户没有再次触摸屏幕,认为是301/302事件,直接交由系统处理。 return super.shouldOverrideUrlLoading(view, url); } else { //否则,属于二次加载某个链接的情况,为了解决拼接参数丢失问题,重新调用loadUrl方法添加固有参数。 loadUrl(url); return true; } } @RequiresApi(api = Build.VERSION_CODES.N) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { boolean handleByChild = null != client && client.shouldOverrideUrlLoading(view, request); if (handleByChild) { return true; } else if (!isTouchByUser()) { return super.shouldOverrideUrlLoading(view, request); } else { loadUrl(request.getUrl().toString()); return true; } } }); } }
|