又到了每次的實際專案開發中的需求討論了。這次是因為做的專案是原生內嵌WebView,所以當我們的WebView在載入網頁的時候,需要有個載入進度條,當然這時候有很多種選擇,但是因為普通的對話方塊型別的載入框太醜,我們就捨棄掉了,而是模仿微信裡面的進度載入條,也就是在WebView 的頂部會有一條線來顯示載入進度。(也就是下方GIF圖中的那個紫紅色的進度條,別問我為啥用紫紅色。我就覺得用這個顏色更加明顯點。O(∩_∩)O~)
宣告大家不要噴哈,有問題可以評論反饋。我做的可能也不是很好
先附上Demo:DEMO
一些關於WebView的基礎我就不說了。大家可以看看
Android之WebView快速上手
OK ,進入我們的正題,我們先要知道怎麼監聽到網頁載入的進度。
監聽網頁載入進度:
我們按照上面的Android之WebView快速上手所說的:
我們知道了WebChromeClient
中有個onProgressChanged
方法可以用來監聽,所以我們複寫onProgressChanged
方法:
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
....
....
....
}
});複製程式碼
好了,我們現在在訪問網頁的時候已經可以拿到了進度值了。也就是newProgress。這裡要注意一個問題,那就是如果你在這裡打上Log你會發現,這個newProgress值不是說按我們想象中那樣,從0慢慢到100,可能就是(0->16->30->100)就返回這四次數字。所以如果我們直接讓我們的進度條按照它的newProgress值來變化,就有個問題,那就是會變化特別大,而且速度也特別快。體驗一點也不好。所以這裡我處理方式是,當newProgress 大於85 的時候,讓他慢慢的在特定時間內載入完剩下的進度,這樣給人的感覺也是很平穩的
自定義進度條:
其實這個自定義進度條很簡單,其實就是畫了一個矩形,然後矩形的width就是根據我們拿到的網頁的進度來實時的變化:
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);
}
}複製程式碼
我們在上面提到。我們在大於85的時候,讓他慢慢的載入完畢,所以我們這裡要有二個方法:
正常方法:
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(); }複製程式碼
繼續補充onProgressChanged方法:
既然我們寫好了自定義進度條的View ,我們回頭再來補充下onProgressChanged
方法:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//如果進度條隱藏則讓它顯示
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);
}
}
});複製程式碼
我們看到了。我們的進度大於85的話,就在一秒鐘內慢慢的載入完,載入完後呼叫hideProgress
方法來隱藏進度條,
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;
}複製程式碼
問題:
實際操作中的問題,這裡我也遇到問題:
- 那就是網頁載入沒有想象中那樣載入一次。網頁可能會有重定向跳轉這種,雖然你可能感覺就開啟了一個連結,你會發現newProgress 從0 -> 100後,會再多次呼叫0->100。這裡我不知道一般大家在做其他APP的WebView進度條的時候,是按照它真實的newProgress來載入,也就是載入了一次全的,然後進度條重新載入一次,再載入一次。還是說只載入第一次的0->100的進度條。
- 我本來想載入第一次進度條,後面的newProgress的重新0->100我就不管了。我就想到重寫
WebViewClient
,因為裡面有二個方法:
然後我就想到定義一個boolean值,這樣豈不是可以在這二個方法裡面賦值,然後用來控制。//當網頁載入完畢後這個方法會被回撥 public void onPageFinished (WebView view, String url) //當網頁開始載入時這個方法會被回撥 public void onPageStarted (WebView view, String url, Bitmap favicon)複製程式碼
可是我打了Log發現,比如我WebView開啟的是https://www.baidu.com
,然後開啟顯示的百度首頁中某個新聞,onPageStarted
並不會呼叫。而onPageFinished
還是會被呼叫,我想了解下什麼時候onPageStarted
不會被去呼叫。 ╮(╯﹏╰)╭
如果大家能幫忙答疑就謝謝了。