Android带加载进度条的WebView

简介: Android带加载进度条的WebView

我们直接上代码,复制就可以用

publicclassWebProgressextendsFrameLayout {
/*** 默认匀速动画最大的时长*/publicstaticfinalintMAX_UNIFORM_SPEED_DURATION=8*1000;
/*** 默认加速后减速动画最大时长*/publicstaticfinalintMAX_DECELERATE_SPEED_DURATION=450;
/*** 95f-100f时,透明度1f-0f时长*/publicstaticfinalintDO_END_ALPHA_DURATION=630;
/*** 95f - 100f动画时长*/publicstaticfinalintDO_END_PROGRESS_DURATION=500;
/*** 当前匀速动画最大的时长*/privatestaticintCURRENT_MAX_UNIFORM_SPEED_DURATION=MAX_UNIFORM_SPEED_DURATION;
/*** 当前加速后减速动画最大时长*/privatestaticintCURRENT_MAX_DECELERATE_SPEED_DURATION=MAX_DECELERATE_SPEED_DURATION;
/*** 默认的高度(dp)*/publicstaticintWEB_PROGRESS_DEFAULT_HEIGHT=3;
/*** 进度条颜色默认*/publicstaticStringWEB_PROGRESS_COLOR="#2483D9";
/*** 进度条颜色*/privateintmColor;
/*** 进度条的画笔*/privatePaintmPaint;
/*** 进度条动画*/privateAnimatormAnimator;
/*** 控件的宽度*/privateintmTargetWidth=0;
/*** 控件的高度*/privateintmTargetHeight;
/*** 标志当前进度条的状态*/privateintTAG=0;
/*** 第一次过来进度show,后面就是setProgress*/privatebooleanisShow=false;
/*** 用来记录不能继续开始*/publicstaticfinalintUN_START=0;
/*** 用来记录已经开始,当开始执行加载动画后就切换到该状态*/publicstaticfinalintSTARTED=1;
/*** 用来记录已经结束*/publicstaticfinalintFINISH=2;
/*** 百分比进度值*/privatefloatmCurrentProgress=0F;
publicWebProgress(Contextcontext) {
this(context, null);
    }
publicWebProgress(Contextcontext, @NullableAttributeSetattrs) {
this(context, attrs, 0);
    }
publicWebProgress(Contextcontext, @NullableAttributeSetattrs, intdefStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
    }
/*** 创建的时候*/@OverrideprotectedvoidonAttachedToWindow() {
super.onAttachedToWindow();
    }
/*** 销毁的时候,注意记得清楚动画资源*/@OverrideprotectedvoidonDetachedFromWindow() {
super.onDetachedFromWindow();
/*** animator cause leak , if not cancel;*/if (mAnimator!=null&&mAnimator.isStarted()) {
mAnimator.cancel();
mAnimator=null;
        }
    }
/*** 初始化操作* @param context                           上下文* @param attrs                             attrs属性* @param defStyleAttr                      defStyleAttr*/privatevoidinit(Contextcontext, AttributeSetattrs, intdefStyleAttr) {
//创建画笔,设置属性mPaint=newPaint();
mColor=Color.parseColor(WEB_PROGRESS_COLOR);
mPaint.setAntiAlias(true);
//设置颜色mPaint.setColor(mColor);
mPaint.setDither(true);
mPaint.setStrokeCap(Paint.Cap.SQUARE);
mTargetWidth=context.getResources().getDisplayMetrics().widthPixels;
mTargetHeight=dip2px(WEB_PROGRESS_DEFAULT_HEIGHT);
    }
/*** 设置单色进度条*/publicvoidsetColor(intcolor) {
this.mColor=color;
mPaint.setColor(color);
    }
/*** 设置单色进度条* @param color                     颜色*/publicvoidsetColor(Stringcolor) {
this.setColor(Color.parseColor(color));
    }
/*** 设置渐变色进度条** @param startColor                        开始颜色* @param endColor                          结束颜色*/publicvoidsetColor(intstartColor, intendColor) {
try {
LinearGradientlinearGradient=newLinearGradient(0, 0, mTargetWidth,
mTargetHeight, startColor, endColor, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
        } catch (Exceptione){
e.printStackTrace();
        }
    }
/*** 设置渐变色进度条** @param startColor                        开始颜色* @param endColor                          结束颜色*/publicvoidsetColor(StringstartColor, StringendColor) {
this.setColor(Color.parseColor(startColor), Color.parseColor(endColor));
    }
/*** 测量方法* @param widthMeasureSpec                  widthMeasureSpec* @param heightMeasureSpec                 heightMeasureSpec*/@OverrideprotectedvoidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) {
intwMode=MeasureSpec.getMode(widthMeasureSpec);
inthMode=MeasureSpec.getMode(heightMeasureSpec);
intw=MeasureSpec.getSize(widthMeasureSpec);
inth=MeasureSpec.getSize(heightMeasureSpec);
if (wMode==MeasureSpec.AT_MOST) {
DisplayMetricsdisplayMetrics=getContext().getResources().getDisplayMetrics();
w=w<=displayMetrics.widthPixels?w : displayMetrics.widthPixels;
        }
if (hMode==MeasureSpec.AT_MOST) {
h=mTargetHeight;
        }
this.setMeasuredDimension(w, h);
    }
@OverrideprotectedvoidonDraw(Canvascanvas) {
    }
@OverrideprotectedvoiddispatchDraw(Canvascanvas) {
canvas.drawRect(0, 0,
mCurrentProgress/100*Float.valueOf(this.getWidth()), this.getHeight(), mPaint);
    }
@OverrideprotectedvoidonSizeChanged(intw, inth, intoldw, intoldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mTargetWidth=getMeasuredWidth();
intscreenWidth=getContext().getResources().getDisplayMetrics().widthPixels;
if (mTargetWidth>=screenWidth) {
CURRENT_MAX_DECELERATE_SPEED_DURATION=MAX_DECELERATE_SPEED_DURATION;
CURRENT_MAX_UNIFORM_SPEED_DURATION=MAX_UNIFORM_SPEED_DURATION;
        } else {
//取比值floatrate= (float) (this.mTargetWidth/ (screenWidth*1.0));
CURRENT_MAX_UNIFORM_SPEED_DURATION= (int) (MAX_UNIFORM_SPEED_DURATION*rate);
CURRENT_MAX_DECELERATE_SPEED_DURATION= (int) (MAX_DECELERATE_SPEED_DURATION*rate);
        }
    }
privatevoidsetFinish() {
isShow=false;
TAG=FINISH;
    }
/*** 开始动画*/privatevoidstartAnim(booleanisFinished) {
floatv=isFinished?100 : 95;
//先清除动画资源if (mAnimator!=null&&mAnimator.isStarted()) {
mAnimator.cancel();
        }
mCurrentProgress= ((int)mCurrentProgress) ==0f?0.00000001f : mCurrentProgress;
if (!isFinished) {
//如果还没有完成ValueAnimatormAnimator=ValueAnimator.ofFloat(mCurrentProgress, v);
floatresidue=1f-mCurrentProgress/100-0.05f;
mAnimator.setInterpolator(newLinearInterpolator());
mAnimator.setDuration((long) (residue*CURRENT_MAX_UNIFORM_SPEED_DURATION));
mAnimator.addUpdateListener(mAnimatorUpdateListener);
mAnimator.start();
this.mAnimator=mAnimator;
        } else {
//如果还没有完成ValueAnimatorsegment95Animator=null;
if (mCurrentProgress<95f) {
segment95Animator=ValueAnimator.ofFloat(mCurrentProgress, 95);
floatresidue=1f-mCurrentProgress/100f-0.05f;
segment95Animator.setInterpolator(newLinearInterpolator());
segment95Animator.setDuration((long) (residue*CURRENT_MAX_DECELERATE_SPEED_DURATION));
segment95Animator.setInterpolator(newDecelerateInterpolator());
segment95Animator.addUpdateListener(mAnimatorUpdateListener);
            }
ObjectAnimatormObjectAnimator=ObjectAnimator.ofFloat(
this, "alpha", 1f, 0f);
mObjectAnimator.setDuration(DO_END_ALPHA_DURATION);
ValueAnimatormValueAnimatorEnd=ValueAnimator.ofFloat(95f, 100f);
mValueAnimatorEnd.setDuration(DO_END_PROGRESS_DURATION);
mValueAnimatorEnd.addUpdateListener(mAnimatorUpdateListener);
AnimatorSetmAnimatorSet=newAnimatorSet();
mAnimatorSet.playTogether(mObjectAnimator, mValueAnimatorEnd);
if (segment95Animator!=null) {
AnimatorSetmAnimatorSet1=newAnimatorSet();
mAnimatorSet1.play(mAnimatorSet).after(segment95Animator);
mAnimatorSet=mAnimatorSet1;
            }
mAnimatorSet.addListener(mAnimatorListener);
mAnimatorSet.start();
mAnimator=mAnimatorSet;
        }
TAG=STARTED;
    }
/*** 创建属性动画监听进度变化的对象*/privateValueAnimator.AnimatorUpdateListenermAnimatorUpdateListener=newValueAnimator.AnimatorUpdateListener() {
@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation) {
floatt= (float) animation.getAnimatedValue();
//更改进度WebProgress.this.mCurrentProgress=t;
//调用invalidate方法刷新UIWebProgress.this.invalidate();
                }
            };
/*** 创建属性动画监听的对象*/privateAnimatorListenerAdaptermAnimatorListener=newAnimatorListenerAdapter() {
@OverridepublicvoidonAnimationEnd(Animatoranimation) {
doEnd();
        }
@OverridepublicvoidonAnimationCancel(Animatoranimation) {
super.onAnimationCancel(animation);
        }
@OverridepublicvoidonAnimationStart(Animatoranimation) {
super.onAnimationStart(animation);
        }
    };
privatevoiddoEnd() {
if (TAG==FINISH&& ((int)mCurrentProgress) ==100f) {
setVisibility(GONE);
mCurrentProgress=0f;
this.setAlpha(1f);
        }
TAG=UN_START;
    }
publicvoidreset() {
mCurrentProgress=0;
if (mAnimator!=null&&mAnimator.isStarted()) {
mAnimator.cancel();
        }
    }
/*** 设置进度* @param progress                          进度值*/publicvoidsetProgress(intprogress) {
// fix 同时返回两个 100,产生两次进度条的问题;if (TAG==UN_START&&progress==100f) {
setVisibility(View.GONE);
return;
        }
if (getVisibility() ==View.GONE) {
setVisibility(View.VISIBLE);
        }
if (progress<95f) {
return;
        }
if (TAG!=FINISH) {
startAnim(true);
        }
    }
publicLayoutParamsofferLayoutParams() {
returnnewLayoutParams(mTargetWidth, mTargetHeight);
    }
privateintdip2px(floatdpValue) {
finalfloatscale=getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue*scale+0.5f);
    }
/*** 显示进度条*/publicvoidshow() {
isShow=true;
setVisibility(View.VISIBLE);
mCurrentProgress=0f;
startAnim(false);
    }
/*** 进度完成后消失*/publicvoidhide() {
setWebProgress(100);
    }
/*** 为单独处理WebView进度条*/publicvoidsetWebProgress(intnewProgress) {
if (newProgress>=0&&newProgress<95) {
if (!isShow) {
show();
            } else {
setProgress(newProgress);
            }
        } else {
setProgress(newProgress);
setFinish();
        }
    }
}
publicclassMainActivityextendsAppCompatActivity {
privateWebViewwebView;
privateWebProgressprogress;
privateTextViewtvTitle;
privateTextViewtvRefresh;
privateRotateAnimationrotate;
@OverrideprotectedvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView=findViewById(R.id.web_view);
progress=findViewById(R.id.progress);
tvTitle=findViewById(R.id.tv_title);
tvRefresh=findViewById(R.id.tv_refresh);
progress.show();
progress.setColor(this.getResources().getColor(R.color.colorAccent),this.getResources().getColor(R.color.colorPrimaryDark));
webView.setWebViewClient(newMyWebViewClient());
webView.setWebChromeClient(newMyWebChromeClient());
finalStringurl="http://www.baidu.com";
webView.loadUrl(url);
tvRefresh.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(Viewview) {
webView.loadUrl(url);
            }
        });
    }
privateclassMyWebViewClientextendsWebViewClient {
//        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)//        @Override//        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {//            String s = request.getUrl().toString();//            X5LogUtils.i("-------shouldOverrideUrlLoading----->21--"+s);//            //view.loadUrl(s);//            //return true;//            return super.shouldOverrideUrlLoading(view, request);//        }@OverridepublicbooleanshouldOverrideUrlLoading(WebViewview, Stringurl) {
//判断重定向的方式一LogUtil.i("-----shouldOverrideUrlLoading---------",url);
WebView.HitTestResulthitTestResult=view.getHitTestResult();
if(hitTestResult==null) {
returnfalse;
            }
if(hitTestResult.getType() ==WebView.HitTestResult.UNKNOWN_TYPE) {
//X5LogUtils.i("-------重定向-------");returnfalse;
            }
view.loadUrl(url);
//X5LogUtils.i("-----shouldOverrideUrlLoading-----2----"+url);//            running++;returntrue;
//return super.shouldOverrideUrlLoading(view, url);        }
@OverridepublicvoidonPageStarted(WebViewview, Stringurl, Bitmapfavicon) {
super.onPageStarted(view, url, favicon);
LogUtil.i("-------onPageStarted-------",url);
//            running = Math.max(running, 1);        }
@OverridepublicvoidonPageFinished(WebViewview, Stringurl) {
super.onPageFinished(view, url);
LogUtil.i("-------onPageFinished-------",url);
//            if (--running==0) {//                //做操作,隐藏加载进度条或者加载loading//                X5LogUtils.i("-------onPageFinished-----结束--");//            }        }
    }
privateclassMyWebChromeClientextendsWebChromeClient {
@OverridepublicvoidonReceivedTitle(WebViewview, Stringtitle) {
super.onReceivedTitle(view, title);
LogUtil.i("-------onReceivedTitle-------",title);
//bar.setTitle(title));getWebTitle(view);
//            if (--running==0) {//                bar.setTitle(title);//            }        }
@OverridepublicvoidonProgressChanged(WebViewview, intnewProgress) {
super.onProgressChanged(view, newProgress);
progress.setWebProgress(newProgress);
        }
    }
privatevoidgetWebTitle(WebViewview){
WebBackForwardListforwardList=view.copyBackForwardList();
WebHistoryItemitem=forwardList.getCurrentItem();
if (item!=null) {
tvTitle.setText(item.getTitle());
// X5LogUtils.i("-------onReceivedTitle----getWebTitle---"+item.getTitle());        }
    }
@OverridepublicbooleanonKeyDown(intkeyCode, KeyEventevent) {
if (keyCode==KeyEvent.KEYCODE_BACK) {
if (webView.canGoBack()) {
webView.goBack();
returntrue;
//退出网页            } else {
handleFinish();
            }
        }
returnfalse;
    }
publicvoidhandleFinish() {
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
finishAfterTransition();
        } else {
finish();
        }
    }
@OverrideprotectedvoidonDestroy() {
try {
if (webView!=null) {
webView.destroy();
webView=null;
            }
if (rotate!=null){
rotate.cancel();
            }
        } catch (Exceptione) {
Log.e("X5WebViewActivity", e.getMessage());
        }
super.onDestroy();
    }
}
相关文章
|
29天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
56 1
|
9天前
|
Android开发
Android Mediatek NVRAM 加载 MAC 地址并禁用 MAC 地址更新
Android Mediatek NVRAM 加载 MAC 地址并禁用 MAC 地址更新
6 0
|
5月前
|
XML API Android开发
Android 自定义View 之 圆环进度条
Android 自定义View 之 圆环进度条
|
23天前
|
XML Java Android开发
Android控件之基础控件——进度条类的view——TextView、Checkbox复选控件、RadioButton单选控件、ToggleButton开关、SeekBar拖动条、menu、弹窗
Android控件之基础控件——进度条类的view——TextView、Checkbox复选控件、RadioButton单选控件、ToggleButton开关、SeekBar拖动条、menu、弹窗
|
3月前
|
XML Android开发 数据格式
安卓和webview交互
安卓和webview交互
26 0
|
5月前
|
XML API Android开发
Android 自定义View 之 饼状进度条
Android 自定义View 之 饼状进度条
|
5月前
|
API Android开发
[Android]图片加载库Glide
[Android]图片加载库Glide
55 0
|
5月前
|
Android开发 UED
[Android]ProgressBar进度条
[Android]ProgressBar进度条
40 0
|
5月前
|
JavaScript 前端开发 Android开发
android开发,使用kotlin学习WebView(详细)
android开发,使用kotlin学习WebView(详细)
147 0
|
5月前
|
XML Java Android开发
Android App开发中使用Glide加载网络图片讲解及实战(附源码 简单易懂)
Android App开发中使用Glide加载网络图片讲解及实战(附源码 简单易懂)
84 0