是不是感觉Material风格的webView加载过程中head下面有一条线跟着网页的加载很酷对不,周末休息2天也随便撸一把,这里拿自己csdn的博客主页献丑了,哈哈。
不多说先来看下效果图:
1. 颜色渐变加载进度条(夜神模拟器)
绿色加载进度条(魅蓝note2)
看图说话:
上图是不是加载网页的时候会有一个进度条在横向加载,比以前网速不好的时候是一片空白给人的感觉友好多了是不,然后效果还不错。
实现思路
就是自己画一条进度线(大家应该都会吧)然后加载到WebView的上面,开始进度条是隐藏的,进度线初始值为1,然后为了效果好一点,初始少于10的进度都让它加载到10的位置,等进度到100的时候0.2秒后隐藏。
请记得添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
说多了都是泪 ,快吃晚饭了,直接代码说话:
代码讲解
步骤一:我们先来话进度线
#WebViewProgressBar.java
package com.losileeya.materialprogresswebview.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.losileeya.materialprogresswebview.R;
/**
* User: Losileeya (847457332@qq.com)
* Date: 2016-04-24
* Time: 14:43
* 类描述:自定义进度条
*
* @version :
*/
public class WebViewProgressBar extends View {
private int progress = 1;//进度默认为1
private final static int HEIGHT = 5;//进度条高度为5
private Paint paint;//进度条的画笔
// 渐变颜色数组
private final static int colors[] = new int[]{0xFF7AD237, 0xFF8AC14A, 0x35B056 }; //int类型颜色值格式:0x+透明值+颜色的rgb值
public WebViewProgressBar(Context context) {
this (context,null);
}
public WebViewProgressBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public WebViewProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint(context);
}
private void initPaint(Context context) {
//颜色渐变从colors[0]到colors[2],透明度从0到1
// LinearGradient shader = new LinearGradient(
// 0, 0,
// 100, HEIGHT,
// colors,
// new float[]{0 , 0.5f, 1.0f},
// Shader.TileMode.MIRROR);
paint=new Paint(Paint.DITHER_FLAG);
paint.setStyle(Paint.Style.STROKE);// 填充方式为描边
paint.setStrokeWidth(HEIGHT);//设置画笔的宽度
paint.setAntiAlias(true);// 抗锯齿
paint.setDither(true);// 使用抖动效果
paint.setColor(context.getResources().getColor(R.color.primary_light));//画笔设置颜色
// paint.setShader(shader);//画笔设置渐变
}
/**
* 设置进度
* @param progress 进度值
*/
public void setProgress(int progress){
this.progress = progress;
invalidate();//刷新画笔
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, getWidth() * progress / 100, HEIGHT, paint);//画矩形从(0.0)开始到(progress,height)的区域
}
}
上面代码的功能就是画一条线(颜色可渐变也可不变色),暴露设置进度的方法给使用者,然后调用 invalidate()刷新进度。
注意:使用渐变时数组的长度和透明度数组长度必须一致,否则会报错的
步骤二:自定义封装webView
#ProgressWebView.java
package com.losileeya.materialprogresswebview.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
/**
* User: Losileeya (847457332@qq.com)
* Date: 2016-04-24
* Time: 14:42
* 类描述:自定义带进度加载条的webView
*
* @version :
*/
public class ProgressWebView extends WebView {
private WebViewProgressBar progressBar;//进度条的矩形(进度线)
private Handler handler;
private WebView mWebView;
public ProgressWebView(Context context, AttributeSet attrs) {
super(context, attrs);
//实例化进度条
progressBar = new WebViewProgressBar(context);
//设置进度条的size
progressBar.setLayoutParams(new ViewGroup.LayoutParams
(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
//刚开始时候进度条不可见
progressBar.setVisibility(GONE);
//把进度条添加到webView里面
addView(progressBar);
//初始化handle
handler = new Handler();
mWebView = this;
initSettings();
}
private void initSettings() {
// 初始化设置
WebSettings mSettings = this.getSettings();
mSettings.setJavaScriptEnabled(true);//开启javascript
mSettings.setDomStorageEnabled(true);//开启DOM
mSettings.setDefaultTextEncodingName("utf-8");//设置字符编码
//设置web页面
mSettings.setAllowFileAccess(true);//设置支持文件流
mSettings.setSupportZoom(true);// 支持缩放
mSettings.setBuiltInZoomControls(true);// 支持缩放
mSettings.setUseWideViewPort(true);// 调整到适合webview大小
mSettings.setLoadWithOverviewMode(true);// 调整到适合webview大小
mSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);// 屏幕自适应网页,如果没有这个,在低分辨率的手机上显示可能会异常
mSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
//提高网页加载速度,暂时阻塞图片加载,然后网页加载好了,在进行加载图片
mSettings.setBlockNetworkImage(true);
mSettings.setAppCacheEnabled(true);//开启缓存机制
setWebViewClient(new MyWebClient());
setWebChromeClient(new MyWebChromeClient());
}
/**
* 自定义WebChromeClient
*/
private class MyWebChromeClient extends WebChromeClient {
/**
* 进度改变的回掉
*
* @param view WebView
* @param newProgress 新进度
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
progressBar.setProgress(100);
handler.postDelayed(runnable, 200);//0.2秒后隐藏进度条
} else if (progressBar.getVisibility() == GONE) {
progressBar.setVisibility(VISIBLE);
}
//设置初始进度10,这样会显得效果真一点,总不能从1开始吧
if (newProgress < 10) {
newProgress = 10;
}
//不断更新进度
progressBar.setProgress(newProgress);
super.onProgressChanged(view, newProgress);
}
}
private class MyWebClient extends WebViewClient {
/**
* 加载过程中 拦截加载的地址url
*
* @param view
* @param url 被拦截的url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
mWebView.loadUrl(url);
return true;
}
/**
* 页面加载过程中,加载资源回调的方法
*
* @param view
* @param url
*/
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
/**
* 页面加载完成回调的方法
*
* @param view
* @param url
*/
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// 关闭图片加载阻塞
view.getSettings().setBlockNetworkImage(false);
}
/**
* 页面开始加载调用的方法
*
* @param view
* @param url
* @param favicon
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
}
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
ProgressWebView.this.requestFocus();
ProgressWebView.this.requestFocusFromTouch();
}
}
/**
*刷新界面(此处为加载完成后进度消失)
*/
private Runnable runnable = new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.GONE);
}
};
}
上面的代码就是把进度线加到webView里面,然后自定义WebChromeClient通过重写onProgressChanged()方法调用 progressBar.setProgress(newProgress)来更新进度,进度到100时再隐藏,是不是思路很清晰,其他的就是一些webView的设置和封装这里都有清楚的注释,自己去看。
使用ProgressWebView加载网页
布局使用:
#activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.losileeya.materialprogresswebview.widget.ProgressWebView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.losileeya.materialprogresswebview.widget.ProgressWebView>
布局看起来是不是很清爽,对了,要的就是之效果:
实际使用也很简单:
#MainActivity.java
package com.losileeya.materialprogresswebview;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.losileeya.materialprogresswebview.widget.ProgressWebView;
public class MainActivity extends AppCompatActivity {
//ProgressWebView
private ProgressWebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (ProgressWebView) findViewById(R.id.webView);//findViewById webView
mWebView.loadUrl("http://blog.csdn.net/u013278099/");//加载网址
mWebView.setFocusable(true);//设置有焦点
mWebView.setFocusableInTouchMode(true);//设置可触摸
}
}
总结:
自定义webView的加载虽然代码不是很难,但是思想还是得有的,好歹也算个自定义控件嘛。记住“只要思想不滑坡,方法总比困难多”。觉得说的不错的,写的也还过得去的给宝宝点个赞,顶一下也是对宝宝的支持给宝宝的动力。
想看一下demo效果的,跟我来——————–》传送门:MaterialProgressWebView.rar