您的位置:首页 > 移动开发

android WebView加载假进度条

2016-06-17 14:12 387 查看
在开发中遇到一个需求给WebView做一个进度条progressBar,一开始直接用下边代码实现webView加载进度:

webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
progressBar.setProgress(newProgress);
}
});


然而用这种方式最后发现progressBar现实非常不流畅,走的一卡一卡的,和微信等进度条差距很大,所以自己就写了一个假进度条,效果还不错,以下是进度条源码:

public class WebViewProgressBar extends ProgressBar {

public final static int CHANGE_FIRST = 3000;//起始快速所走长度
public final static int CHANGE_SECOND = 9000;//中间减速段长度和起始长度总和
public final static int TIME_FIRST = 1000;//起始快速所需时间
public final static int TIME_SECOND = 5000;//中间减速段时间和起始时间总和
public final static int TIME_SLEEP = 10;//ProgressBar每次更新进度时间

private int schedule = 0;// web加载时进度条当前进度
private int isFinishSchedule = 100000;// web加载完成时进度条当前进度
private boolean isFinish = false;//web是否加载完成
private myThread myThread;

public WebViewProgressBar(Context context) {
super(context);
}

public WebViewProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}

public WebViewProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

/**
* 进度条开始加载,刷新可重复调用
*/
public void startProgress() {
setVisibility(View.VISIBLE);
setMax(10000);
setProgress(0);
isFinish = false;
if (myThread!= null){
myThread.interrupt();
}
myThread = new myThread();
myThread.start();
}

/**
* 加载完成结束进度条
*/
public void finishProgress() {
isFinish = true;
}

Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
schedule = msg.what;
setProgress(msg.what);
if(msg.what > isFinishSchedule){
Animation animation = new AlphaAnimation(1.0f, 0.3f);
animation.setDuration(400);
startAnimation(animation);
}
if (msg.what >= 10000) {
setVisibility(View.GONE);
}
}

};

public class myThread extends Thread {
@Override
public void run() {

try {
int time = 0;
int n = (TIME_SECOND - TIME_FIRST)/TIME_SLEEP;//中间慢速段等差数列次数
int d = (CHANGE_SECOND - CHANGE_FIRST)/(n-1);//中间慢速段每次前进长度等差数列公差
while (true){
if (isFinish) {
finishProgressSchedule();
return;
}
Message message = new Message();
if (time <= TIME_FIRST) {//前部分快速速
Thread.sleep(TIME_SLEEP);
time = time + TIME_SLEEP;
message.what = (time/TIME_SLEEP)*(CHANGE_FIRST*TIME_SLEEP)/TIME_FIRST;
mHandler.sendMessage(message);
} else if (time > TIME_FIRST && time <= TIME_SECOND) {//中间慢慢减速
Thread.sleep(TIME_SLEEP);
time = time + TIME_SLEEP;
int thisN = (time-TIME_FIRST)/TIME_SLEEP;
int An = CHANGE_FIRST+(thisN-1)*d;//计算当前该走到位置
message.what = An;
mHandler.sendMessage(message);
}else if (time >TIME_SECOND){
for (int a = 1; a <= 1000; a++) {//60秒未加载完,进度条直接结束
Thread.sleep(60);
if (a == 1000) {//当访问超时快速结束
finishProgress();
}
if (isFinish) {
finishProgressSchedule();
return;
}
}
}
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

/**
* 子线程中ProgressBar加载完成快速走完剩余进度
*/
private void finishProgressSchedule() throws InterruptedException {
isFinishSchedule = schedule;
int i = schedule;
do {
Message message = new Message();
Thread.sleep(TIME_SLEEP);
i = i+100;
message.what = i;
mHandler.sendMessage(message);
}while (i <= 10000);
}
}


上边代码继承了ProgressBar(这儿都指的是横向进度条),在里面有一个新线程通过hander消息控制进度条的进度,整个进度条最大为10000,分为3部分,前边3000速度比较快,而3000-9000则速度减慢前进,前两段总用时为5000,然后剩下的1000则不动等待数据加载完成,以上这些数据可根据自己项目修改。下面是个简单例子:

public class ProgressActivity extends AppCompatActivity{

WebView webView;
WebViewProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acticity_progress);
webView = (WebView) findViewById(R.id.webView);
progressBar = (WebViewProgressBar) findViewById(R.id.progressBar);
webView.getSettings().setJavaScriptEnabled(true);
refreshWebView();
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress == 100){
//加载完成
progressBar.finishProgress();
}
}
});
Button button = (Button) findViewById(R.id.button3);
Button button1 = (Button) findViewById(R.id.button4);
//刷新页面,对应可放在下拉刷新机制中
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
refreshWebView();
}
});
//手动结束进度条
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressBar.finishProgress();
}
});

}

public void refreshWebView(){
webView.loadUrl("https://www.baidu.com/");
progressBar.startProgress();
}

}


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="刷新页面"
android:id="@+id/button3" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="结束进度条"
android:id="@+id/button4" />
</LinearLayout>
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/linearLayout">

</WebView>

<com.lxq.myapplication.popup.WebViewProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progressBar" />
</RelativeLayout>


上边是简单的小例子,加载一个Web页面,进度条开始,当页面加载完成时,调用finishProgress();结束进度条。没有做下拉刷新组件,不过下拉时掉用progressBar.startProgress();当前进度会清零重新开始。

自己写的拙作,希望各位互相交流指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息