package com.example.lghdialog.webview; import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.support.v4.view.MotionEventCompat; import android.support.v4.view.NestedScrollingChild; import android.support.v4.view.NestedScrollingChildHelper; import android.support.v4.view.VelocityTrackerCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.webkit.WebChromeClient; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.ProgressBar; /** * Created by Administrator on 2016/5/27. */ public class LghCustomWebView extends WebView implements NestedScrollingChild { private WebSettings settings; private String Url; private ProgressBar progressBar; private WebChromeClient.CustomViewCallback customViewCallback; private FrameLayout videoView; private View customView; private Context context; private View progressLayout; private int progressId; private WebChromeClient chromeClient; private ScreenChangeListener listener; private String loadType="GET"; public static final String POST="POST"; public static final String GET="GET"; //private RequestParams params; private NestedScrollingChildHelper mChildHelper; private int downY; private final int[] mScrollOffset=new int[2]; private final int[] mScrollConsumed=new int[2]; private int mMinimumVelocity; private int mMaximumVelocity; private VelocityTracker mVelocityTracker; public interface ScreenChangeListener{ public void landscape(); public void portrait(); } public interface WebViewTitleReceiver{ public void getTitle(String title); } private WebViewTitleReceiver receiver; public LghCustomWebView withWebViewTitleReceiver(WebViewTitleReceiver receiver){ this.receiver=receiver; return this; } // public CustomWebView withParams(RequestParams params){ // this.params=params; // return this; // } public LghCustomWebView withURL(String url){ this.Url=url; return this; } public LghCustomWebView startLoad(){ if (Url!=null){ switch (loadType){ case POST: // if (params!=null){ // String postData=params.toString(); // this.postUrl(Url, EncodingUtils.getBytes(postData,"utf-8")); // } break; case GET: this.loadUrl(Url); break; } } return this; } private void isSettingNull(){ if (settings==null){ settings=this.getSettings(); } } public LghCustomWebView withScreenChangeListener(ScreenChangeListener listener){ this.listener=listener; return this; } //支持JavaScript public LghCustomWebView withJavaScriptEnabled(boolean isEnabled){ isSettingNull(); settings.setJavaScriptEnabled(isEnabled); return this; } public LghCustomWebView withLoadType(String type){ this.loadType=type; return this; } public LghCustomWebView withJavaScriptCanOpenWindowsAutomatically(boolean isEnabled){ isSettingNull(); settings.setJavaScriptCanOpenWindowsAutomatically(isEnabled); return this; } //使页面自适应屏幕 public LghCustomWebView withUseWideViewPort(boolean isEnabled){ isSettingNull(); settings.setUseWideViewPort(isEnabled); return this; } //缩放至屏幕的大小 public LghCustomWebView withLoadWithOverviewMode(boolean isEnabled){ isSettingNull(); settings.setLoadWithOverviewMode(isEnabled); return this; } //支持自动加载图片 public LghCustomWebView withLoadsImagesAutomatically(boolean isEnabled){ isSettingNull(); settings.setLoadsImagesAutomatically(isEnabled); return this; } public LghCustomWebView withUserAgent(String userAgent){ isSettingNull(); settings.setUserAgentString(settings.getUserAgentString()+userAgent); return this; } public LghCustomWebView withDomStorageEnabled(boolean isEnabled){ isSettingNull(); settings.setDomStorageEnabled(isEnabled); return this; } public LghCustomWebView withSaveFormData(boolean isEnabled){ isSettingNull(); settings.setSaveFormData(isEnabled); return this; } public LghCustomWebView withLoadUrlType(){ isSettingNull(); settings.setDefaultTextEncodingName("gbk"); return this; } public LghCustomWebView(Context context) { this(context,null); } public LghCustomWebView(Context context, AttributeSet attrs) { super(context, attrs); this.context=context; mChildHelper=new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); ViewConfiguration configuration= ViewConfiguration.get(context); mMinimumVelocity=configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity=configuration.getScaledMaximumFlingVelocity(); } public LghCustomWebView withProgressView(ProgressBar progressView){ this.progressBar=progressView; return this; } public LghCustomWebView withWebviewChromeClient(){ this.chromeClient=new CustomWebViewChromeClient(); this.setWebChromeClient(this.chromeClient); return this; } public LghCustomWebView withWebviewChromeClient(WebChromeClient client){ this.setWebChromeClient(client); return this; } public LghCustomWebView withWebViewClient(){ this.setWebViewClient(new CustomWebViewClient()); return this; } public LghCustomWebView withWebViewClient(WebViewClient client){ this.setWebViewClient(client); return this; } public LghCustomWebView withVideoView(FrameLayout videoView){ this.videoView=videoView; return this; } public LghCustomWebView withVideoProgressLayoutId(int id){ this.progressId=id; return this; } public class CustomWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { progressBar.setProgress(0); progressBar.setVisibility(GONE); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { progressBar.setVisibility(VISIBLE); super.onPageStarted(view,url,favicon); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); receiver.getTitle(""); } } public class CustomWebViewChromeClient extends WebChromeClient { @Override public void onProgressChanged(WebView view, int newProgress) { if (progressBar!=null){ progressBar.setProgress(newProgress); } } @Override public void onShowCustomView(View view, CustomViewCallback callback) { if (customView!=null){ callback.onCustomViewHidden(); return; } customView=view; customViewCallback=callback; videoView.addView(view); videoView.setVisibility(VISIBLE); if (listener!=null){ listener.landscape(); } setFullScreen(); } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); if (receiver!=null){ receiver.getTitle(title); } } @Override public void onHideCustomView() { if (customView==null){ return; } if (listener!=null){ listener.portrait(); } exitFullScreen(); customView.setVisibility(GONE); videoView.removeView(customView); customView=null; videoView.setVisibility(GONE); customViewCallback.onCustomViewHidden(); } @Override public View getVideoLoadingProgressView() { if (progressLayout==null){ LayoutInflater inflater= LayoutInflater.from(context); progressLayout=inflater.inflate(progressId,null); } return progressLayout; } } private void setFullScreen(){ ((Activity)context).getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); ((Activity)context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } private void exitFullScreen(){ WindowManager.LayoutParams attrs=((Activity)context).getWindow().getAttributes(); attrs.flags &=(~WindowManager.LayoutParams.FLAG_FULLSCREEN); ((Activity)context).getWindow().setAttributes(attrs); ((Activity)context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); // ((Activity)context).getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); ((Activity)context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } public boolean WebViewGoBack(){ if (customView!=null){ chromeClient.onHideCustomView(); return true; }else { if (this.canGoBack()){ this.goBack(); }else { return false; } } return true; } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); boolean eventAddedToVelocityTracker=false; final int action= MotionEventCompat.getActionMasked(event); if (mVelocityTracker==null){ mVelocityTracker= VelocityTracker.obtain(); } switch (action){ case MotionEvent.ACTION_DOWN: downY= (int) event.getRawY(); startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); break; case MotionEvent.ACTION_MOVE: int moveY= (int) event.getRawY(); int dy=-(moveY-downY); downY=moveY; if (dispatchNestedPreScroll(0,dy,mScrollConsumed,mScrollOffset)){ dy-=mScrollConsumed[1]; scrollBy(0,dy); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mVelocityTracker.addMovement(event); eventAddedToVelocityTracker=true; mVelocityTracker.computeCurrentVelocity(1000,mMaximumVelocity); int mScrollPointerId= MotionEventCompat.getPointerId(event, MotionEventCompat.getActionIndex(event)); float vY=-VelocityTrackerCompat.getYVelocity(mVelocityTracker,mScrollPointerId); if (Math.abs(vY)>mMinimumVelocity&&!dispatchNestedPreFling(0,vY)){ dispatchNestedFling(0,vY,true); } resetTouch(); break; } if (!eventAddedToVelocityTracker){ mVelocityTracker.addMovement(event); } return true; } private void resetTouch(){ if (mVelocityTracker!=null){ mVelocityTracker.clear(); } stopNestedScroll(); } @Override public void setNestedScrollingEnabled(boolean enabled) { mChildHelper.setNestedScrollingEnabled(enabled); } @Override public boolean startNestedScroll(int axes) { return mChildHelper.startNestedScroll(axes); } @Override public void stopNestedScroll() { mChildHelper.stopNestedScroll(); } @Override public boolean hasNestedScrollingParent() { return mChildHelper.hasNestedScrollingParent(); } @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow); } @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); } @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed); } @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { return mChildHelper.dispatchNestedPreFling(velocityX, velocityY); } }