android WebView加载假进度条

本文介绍了一种自定义WebView加载进度条的方法,通过创建一个新的WebViewProgressbar类来模拟平滑的加载过程,解决了原生进度条显示不流畅的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发中遇到一个需求给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();当前进度会清零重新开始。

自己写的拙作,希望各位互相交流指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值