又到了每次的實(shí)際項(xiàng)目開(kāi)發(fā)中的需求討論了。這次是因?yàn)樽龅捻?xiàng)目是原生內(nèi)嵌WebView倔约,所以當(dāng)我們的WebView在加載網(wǎng)頁(yè)的時(shí)候秃殉,需要有個(gè)加載進(jìn)度條,當(dāng)然這時(shí)候有很多種選擇浸剩,但是因?yàn)槠胀ǖ膶?duì)話(huà)框類(lèi)型的加載框太丑钾军,我們就舍棄掉了,而是模仿微信里面的進(jìn)度加載條绢要,也就是在WebView 的頂部會(huì)有一條線來(lái)顯示加載進(jìn)度吏恭。(也就是下方GIF圖中的那個(gè)紫紅色的進(jìn)度條,別問(wèn)我為啥用紫紅色重罪。我就覺(jué)得用這個(gè)顏色更加明顯點(diǎn)樱哼。O(∩_∩)O~)
聲明大家不要噴哈,有問(wèn)題可以評(píng)論反饋蛆封。我做的可能也不是很好
先附上Demo:DEMO
一些關(guān)于WebView的基礎(chǔ)我就不說(shuō)了唇礁。大家可以看看
Android之WebView快速上手
OK ,進(jìn)入我們的正題,我們先要知道怎么監(jiān)聽(tīng)到網(wǎng)頁(yè)加載的進(jìn)度惨篱。
監(jiān)聽(tīng)網(wǎng)頁(yè)加載進(jìn)度:
我們按照上面的Android之WebView快速上手所說(shuō)的:
我們知道了WebChromeClient
中有個(gè)onProgressChanged
方法可以用來(lái)監(jiān)聽(tīng)盏筐,所以我們復(fù)寫(xiě)onProgressChanged
方法:
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
....
....
....
}
});
好了,我們現(xiàn)在在訪問(wèn)網(wǎng)頁(yè)的時(shí)候已經(jīng)可以拿到了進(jìn)度值了砸讳。也就是newProgress琢融。這里要注意一個(gè)問(wèn)題界牡,那就是如果你在這里打上Log你會(huì)發(fā)現(xiàn),這個(gè)newProgress值不是說(shuō)按我們想象中那樣漾抬,從0慢慢到100宿亡,可能就是(0->16->30->100)就返回這四次數(shù)字。所以如果我們直接讓我們的進(jìn)度條按照它的newProgress值來(lái)變化纳令,就有個(gè)問(wèn)題挽荠,那就是會(huì)變化特別大,而且速度也特別快平绩。體驗(yàn)一點(diǎn)也不好圈匆。所以這里我處理方式是,當(dāng)newProgress 大于85 的時(shí)候捏雌,讓他慢慢的在特定時(shí)間內(nèi)加載完剩下的進(jìn)度跃赚,這樣給人的感覺(jué)也是很平穩(wěn)的
自定義進(jìn)度條:
其實(shí)這個(gè)自定義進(jìn)度條很簡(jiǎn)單,其實(shí)就是畫(huà)了一個(gè)矩形性湿,然后矩形的width就是根據(jù)我們拿到的網(wǎng)頁(yè)的進(jìn)度來(lái)實(shí)時(shí)的變化:
public class WebProgressBarView extends View{
....
....
....
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = MeasureSpec.getSize(widthMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float result = mWidth * ((float) mCurProgress / (float) 100);
canvas.drawRect(0, 0, result, mHeight, mPaint);
}
}
我們?cè)谏厦嫣岬轿嘲痢N覀冊(cè)诖笥?5的時(shí)候,讓他慢慢的加載完畢肤频,所以我們這里要有二個(gè)方法:
- 正常方法:
public void setNormalProgress(int mCurProgress){
this.mCurProgress = mCurProgress;
postInvalidate();
}
2.慢慢加載的方法:
public void setCurProgress(long time, final EventEndListener endListener){
ValueAnimator animator = ValueAnimator.ofInt(mCurProgress,100);
animator.setDuration(time);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setNormalProgress((Integer) animation.getAnimatedValue());
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
if(endListener != null){
endListener.onEndEvent();
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
繼續(xù)補(bǔ)充onProgressChanged方法:
既然我們寫(xiě)好了自定義進(jìn)度條的View ,我們回頭再來(lái)補(bǔ)充下onProgressChanged
方法:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//如果進(jìn)度條隱藏則讓它顯示
if (View.GONE == progressBarView.getVisibility()) {
progressBarView.setVisibility(View.VISIBLE);
}
if (newProgress >= 85) {
if (isContinue) {
return;
}
isContinue = true;
progressBarView.setCurProgress(1000, new WebProgressBarView.EventEndListener() {
@Override
public void onEndEvent() {
isContinue = false;
if (progressBarView.getVisibility() == View.VISIBLE) {
hideProgress();
}
}
});
} else {
progressBarView.setNormalProgress(newProgress);
}
}
});
我們看到了叹括。我們的進(jìn)度大于85的話(huà),就在一秒鐘內(nèi)慢慢的加載完着裹,加載完后調(diào)用hideProgress
方法來(lái)隱藏進(jìn)度條领猾,
private void hideProgressWithAnim() {
AnimationSet animation = getDismissAnim(MainActivity.this);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
progressBarView.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
progressBarView.startAnimation(animation);
}
private AnimationSet getDismissAnim(Context context) {
AnimationSet dismiss = new AnimationSet(context, null);
AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f);
alpha.setDuration(1000);
dismiss.addAnimation(alpha);
return dismiss;
}
問(wèn)題:
實(shí)際操作中的問(wèn)題,這里我也遇到問(wèn)題:
- 那就是網(wǎng)頁(yè)加載沒(méi)有想象中那樣加載一次骇扇。網(wǎng)頁(yè)可能會(huì)有重定向跳轉(zhuǎn)這種,雖然你可能感覺(jué)就打開(kāi)了一個(gè)鏈接面粮,你會(huì)發(fā)現(xiàn)newProgress 從0 -> 100后少孝,會(huì)再多次調(diào)用0->100。這里我不知道一般大家在做其他APP的WebView進(jìn)度條的時(shí)候熬苍,是按照它真實(shí)的newProgress來(lái)加載稍走,也就是加載了一次全的,然后進(jìn)度條重新加載一次柴底,再加載一次婿脸。還是說(shuō)只加載第一次的0->100的進(jìn)度條。
- 我本來(lái)想加載第一次進(jìn)度條柄驻,后面的newProgress的重新0->100我就不管了狐树。我就想到重寫(xiě)
WebViewClient
,因?yàn)槔锩嬗卸€(gè)方法:
//當(dāng)網(wǎng)頁(yè)加載完畢后這個(gè)方法會(huì)被回調(diào)
public void onPageFinished (WebView view, String url)
//當(dāng)網(wǎng)頁(yè)開(kāi)始加載時(shí)這個(gè)方法會(huì)被回調(diào)
public void onPageStarted (WebView view, String url, Bitmap favicon)
然后我就想到定義一個(gè)boolean值鸿脓,這樣豈不是可以在這二個(gè)方法里面賦值抑钟,然后用來(lái)控制涯曲。
可是我打了Log發(fā)現(xiàn),比如我WebView打開(kāi)的是https://www.baidu.com
在塔,然后打開(kāi)顯示的百度首頁(yè)中某個(gè)新聞,onPageStarted
并不會(huì)調(diào)用幻件。而onPageFinished
還是會(huì)被調(diào)用,我想了解下什么時(shí)候onPageStarted
不會(huì)被去調(diào)用蛔溃。 ╮(╯﹏╰)╭
如果大家能幫忙答疑就謝謝了绰沥。