Welcome to the PkWebView wiki!
- WebView组件的封装,实现秒开
- 项目地址:github.com/Peakmain/Pk…
- 使用文档链接: github.com/Peakmain/Pk…
怎样使用
Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
but If it is a new version of Android studio,Add it in your root setting.gradle at the end of repositories:
dependencyResolutionManagement {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.Peakmain:PkWebView:+'
}
功能列表
一、Application中初始化WebView参数
class App : Application() {
override fun onCreate() {
PkWebViewInit.Builder(this)
//设置WebViewSetting
.setWebViewSetting(DefaultInitWebViewSetting())
//设置WebViewClient
.setWebViewClient(DefaultWebViewClientCallback())
//设置WebViewChromeClient
.setWebViewChromeClient(DefaultWebViewChromeClientCallback())
//设置LoadingView
.setLoadingWebViewState(LoadingWebViewState.HorizontalProgressBarLoadingStyle)
.setLoadingView(ReplaceLoadingConfigImpl())
//设置没有网络View
.setNoNetWorkView(com.peakmain.webview.R.layout.webview_no_network, null)
.setNoNetWorkView(FrameLayout(this), null)
//设置userAgent
.setUserAgent(BuildConfig.config.userAgent)
//设置WebView的数量
.setWebViewCount(5)
//设置接收H5通信的协议
.registerEntities(OnlineServiceHandle::class.java, PageActionHandle::class.java)
//设置解析url中的params的key
.setEventParamsKey("param")
//创建WebView
.build()
super.onCreate()
}
}
1、自定义定制WebViewSetting
你可以根据自己的需求定制 WebView 的设置。我们只需要创建一个继承自 InitWebViewSetting 的类,然后重写其中的 initWebViewSetting() 方法,即可自定义 WebView 的设置。
比如,我们可以创建一个 ReplaceInitWebViewSetting 类,来替换默认的 WebView 设置。在其中,我们可以通过 webView.settings 对象来设置 WebView 的一些属性,如下所示:
public class ReplaceInitWebViewSetting extends InitWebViewSetting {
@Override
public void initWebViewSetting(WebView webView, String userAgent) {
super.initWebViewSetting(webView, userAgent);
// 设置 WebView 的 UserAgent
String newUA = "...";
webView.getSettings().setUserAgentString(newUA);
// 设置 WebView 支持 JavaScript
webView.getSettings().setJavaScriptEnabled(true);
// 设置 WebView 缓存模式
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 设置 WebView 允许加载本地文件
webView.getSettings().setAllowFileAccess(true);
// 设置 WebView 的字体缩放
webView.getSettings().setTextZoom(100);
}
}
在实现自定义设置之后,我们只需要在应用中使用 PkWebViewInit.Builder().setWebViewSetting(ReplaceInitWebViewSetting()) 的方式即可将其载入应用,并实现自定义设置
2、自定义定制WebViewClient
你可以根据自己的需求定制WebViewClient。我们只需要创建一个继承自WebViewClientCallback 的类,然后重写其中的方法,即可自定义 WebViewClient
比如,我们可以创建一个 ReplaceWebViewClient 类,来替换默认的 WebViewClient。在其中,我们可以通过重写 shouldOverrideUrlLoading() 方法来自定义处理 WebView 页面跳转的方式,比如在用户点击链接时,通过自定义方式来处理跳转逻辑。同时,我们还可以重写 onPageStarted() 和 onPageFinished() 方法,来实现 WebView 页面加载时的一些自定义功能,例如自定义加载动画、页面计时等
此外,我们还可以通过重写 onReceivedError() 方法来自定义 WebView 加载错误时的处理方式,以及通过重写 shouldInterceptRequest() 方法来自定义 WebView 加载资源时的请求拦截逻辑等等。
下面是一个 ReplaceWebViewClient 类的示例代码,仅供参考:
class ReplaceWebViewClient : WebViewClientCallback() {
override fun onPageStarted(view: WebView?, url: String?, fragment: WebViewFragment?) {
// 自定义页面加载开始时的逻辑
}
override fun onPageFinished(view: WebView?, url: String?, fragment: WebViewFragment?) {
// 自定义页面加载结束时的逻辑
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?, fragment: WebViewFragment?): Boolean {
// 自定义页面跳转的方式
// 如果需要自定义处理,可以返回 true 并执行自定义代码
// 如果不需要自定义处理,则可以返回 false,以使用 WebView 默认的跳转方式
return false
}
override fun onReceivedError(view: WebView?, err: Int, des: String?, url: String?, fragment: WebViewFragment?) {
// 自定义页面加载错误时的处理方式
}
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
// 自定义拦截资源请求的逻辑
// 如果需要拦截请求,则返回自定义的 WebResourceResponse 对象,否则返回 null
return null
}
}
在实现自定义WebViewClient之后,我们只需要在应用中使用 PkWebViewInit.Builder().setWebViewClient(ReplaceWebViewClient()) 的方式即可将其载入应用,并实现自定义WebViewClient
3、自定义定制WebViewChromeClient
你可以根据自己的需求定制WebViewChromeClient。我们只需要创建一个继承自WebViewChromeClientCallback的类,然后重写其中的方法,即可自定义 WebViewChromeClient
class ReplaceWebViewChromeClientCallback : WebViewChromeClientCallback() {
override fun onReceivedTitle(view: WebView?, title: String?, fragment: WebViewFragment?) {
// 在页面加载完成后,获取页面标题,并对其进行自定义处理
Log.e("TAG", "收到标题:$title")
}
override fun onProgressChanged(view: WebView?, newProgress: Int, fragment: WebViewFragment?) {
// 在页面加载过程中,获取当前页面的加载进度,并对 UI 进行自定义更新
Log.e("TAG", "进度条发生变化:$newProgress")
}
override fun openFileInput(
fileUploadCallbackFirst: ValueCallback<Uri>?,
fileUploadCallbackSecond: ValueCallback<Array<Uri>>?,
acceptType: String?
) {
// 拦截 WebView 上的文件上传操作,并对上传的文件进行自定义处理
// 如果您不需要处理文件上传,请直接忽略此方法
}
}
在实现自定义WebViewChromeClientCallback之后,我们只需要在应用中使用 PkWebViewInit.Builder().setWebViewChromeClientCallback(ReplaceWebViewChromeClientCallback()) 的方式即可将其载入应用,并实现自定义WebViewChromeClientCallback
4、自定义LoadingView
①、setLoadingWebViewState 加载loadingView一共有4种状态
- NotLoading:不加载loading
- HorizontalProgressBarLoadingStyle:水平进度条加载loading
- ProgressBarLoadingStyle:圆圈加载loading
- CustomLoadingStyle:自定义加载样式
sealed class LoadingWebViewState {
object NotLoading : LoadingWebViewState()
object HorizontalProgressBarLoadingStyle : LoadingWebViewState()
object ProgressBarLoadingStyle : LoadingWebViewState()
object CustomLoadingStyle : LoadingWebViewState()
}
如果需要使用自定义Loading,setLoadingWebViewState一定要指定为CustomLoadingStyle
PkWebViewInit.Builder(this).setLoadingWebViewState(LoadingWebViewState.CustomLoadingStyle)
②、自定义LoadingView
我们只需要创建一个类,继承LoadingViewConfig,并重写其中的方法即可。 下面是一个自定义loading的例子
class ReplaceLoadingConfigImpl : LoadingViewConfig {
private lateinit var mAppProgressLoadingView: AppProgressLoadingView
private var isShowLoading: Boolean = false
override fun isShowLoading(): Boolean {
return isShowLoading
}
override fun getLoadingView(context: Context): View {
if (!::mAppProgressLoadingView.isInitialized) {
mAppProgressLoadingView = AppProgressLoadingView(context)
}
isShowLoading = true
return mAppProgressLoadingView
}
override fun hideLoading() {
isShowLoading = false
mAppProgressLoadingView.visibility = View.GONE
}
override fun showLoading(context: Context?) {
if (!::mAppProgressLoadingView.isInitialized && context != null) {
mAppProgressLoadingView = AppProgressLoadingView(context)
}
isShowLoading=true
mAppProgressLoadingView.visibility = View.VISIBLE
}
}
5、自定义没有网络的View
①、根据id添加没有网络的View
PkWebViewInit.Builder(this).setNoNetWorkView(com.peakmain.webview.R.layout.webview_no_network, null)
②、根据view添加没有网络的View
PkWebViewInit.Builder(this).setNoNetWorkView(FrameLayout(this), null)
第二个参数是是个函数方法,添加View成功之后,可以做些网络错误View的处理
PkWebViewInit.Builder(this)
.setNoNetWorkView(FrameLayout(this)) { view ->
view.findViewById<TextView>(R.id.tv_retry).setOnClickListener {
// 在这里处理点击“重试”按钮后的逻辑
Toast.makeText(this, "网络错误,请重试", Toast.LENGTH_SHORT).show()
}
}
6、设置UserAgent
PkWebViewInit.Builder(this).setUserAgent("android")
7、设置WebView的数量
PkWebViewInit.Builder(this).setWebViewCount(5)
8、设置接收H5通信的协议
您可以使用registerEntities方法来设置接收H5通信的协议。这个方法接收一个参数数组,您可以在其中添加您想要接收的协议
PkWebViewInit.Builder(this).registerEntities(OnlineServiceHandle::class.java, PageActionHandle::class.java)
接下来,让我们来看一下如何设置接收协议所需的类。在这个类上方,我们需要添加一个名为Handler的注解,该注解需要指定scheme和authority这两个参数
@Handler(scheme = BuildConfig.scheme, authority = ["onlineService"])
class OnlineServiceHandle {
@HandlerMethod(path = BuildConfig.path)
fun webPolicyAlert(event: WebViewModelEvent): HandleResult {
// 在这里完成接收协议的逻辑
return HandleResult.Consumed
}
}
二、H5Utils启动WebViewActivity
H5Utils()
.isShowToolBar(false)
//.setLoadingWebViewState(LoadingWebViewState.ProgressBarLoadingStyle)
.updateStatusBar { title, activity ->
if (title.contains("商城")) {
activity?.updateStateBar(StatusBarState.NoStatusModeState)
} else {
activity?.updateStateBar()
}
}
.updateToolBar { title, activity ->
if (title.contains("商城")) {
activity?.showToolbar(false)
activity?.showHeadView(true)
} else {
activity?.showToolbar(true)
activity?.showHeadView(false)
/* activity?.setOnClickListener({
activity.finish()
}) {
Toast.makeText(it.context, "点击右边", Toast.LENGTH_LONG).show()
}*/
activity?.setToolbarStyle { toolbar, ivLeft, tvTitle, tvRight ->
//toolbar?.setBackgroundColor(Color.TRANSPARENT)
/* ivLeft?.setImageResource()
tvTitle?.apply {
setTextColor(Color.RED)
}
tvRight?.visibility = View.VISIBLE*/
}
}
}
.setHeadContentView(R.layout.hotel_list_head) {
}
.setHandleUrlParamsCallback(HandlerUrlParamsImpl())
.startActivityForResult(
this, launcher,
WebViewConfigBean(
BuildConfig.config.url
)
)
1、是否有ToolBar
false代表没有ToolBar,true则表示有
H5Utils()
.isShowToolBar(false)
2、设置加载LoadingView
这里和上面说的自定义LoadingView一样,这里就不阐述
H5Utils()
.setLoadingWebViewState(LoadingWebViewState.ProgressBarLoadingStyle)
3、设置状态栏颜色
可以根据title设置不同的状态栏颜色
H5Utils().updateStatusBar { title, activity ->
if (title.contains("商城")) {
activity?.updateStateBar(StatusBarState.NoStatusModeState)
} else {
activity?.updateStateBar()
}
}
activity的updateStateBar有两个参数 ①、状态栏的状态一共有4种状态,默认是黑色字体
sealed class StatusBarState : Parcelable {
/**
* 黑色的字体
*/
object LightModeState : StatusBarState()
/**
* 白色的字体
*/
object DartModeState : StatusBarState()
/**
* 自定义状态栏颜色
*/
object StatusColorState : StatusBarState()
/**
* 隐藏状态栏
*/
object NoStatusModeState : StatusBarState()
}
②、statusBarColor:设置状态栏的颜色,默认是白色 源码
fun updateStateBar(
statusBarState: StatusBarState = StatusBarState.LightModeState,
statusBarColor: Int = Color.WHITE
)
4、设置头部布局
H5Utils().setHeadContentView(R.layout.hotel_list_head) {
//可以对头部的view做处理,假设有以下TextView
it.findViewById(R.id.tv_title).setOnClickListener{}
}
5、toolBar的处理,可以根据title是否显示ToolBar,是否显示头部等
H5Utils().updateToolBar { title, activity ->
if (title.contains("商城")) {
activity?.showToolbar(false)
activity?.showHeadView(true)
} else {
activity?.showToolbar(true)
activity?.showHeadView(false)
/* activity?.setOnClickListener({
activity.finish()
}) {
Toast.makeText(it.context, "点击右边", Toast.LENGTH_LONG).show()
}*/
activity?.setToolbarStyle { toolbar, ivLeft, tvTitle, tvRight ->
//toolbar?.setBackgroundColor(Color.TRANSPARENT)
/* ivLeft?.setImageResource()
tvTitle?.apply {
setTextColor(Color.RED)
}
tvRight?.visibility = View.VISIBLE*/
}
}
}
6、解析url中参数,封装成不同的对象
首先你需要定义一个实体类,继承WebViewEvent类
data class WebViewModelEvent(
var webViewModel: WebViewModel? = null,
var newHybridModel: NewHybridModel? = null
) : WebViewEvent()
data class WebViewModel(
var status: Int = 1,
var data: HashMap<String, String>?,
var callId: String = "" //用于给前端的协议
)
接下来,我们可以自定义一个类,并实现HandleUrlParamsCallback接口的handleUrlParamsCallback方法。在这个方法中,我们可以实现对URL中参数的解析,并将其封装成不同的对象。例如
class HandlerUrlParamsImpl : HandleUrlParamsCallback<WebViewModelEvent> {
override fun handleUrlParamsCallback(uri: Uri?, path: String?): WebViewModelEvent {
val params = uri?.getQueryParameter("param")
val webViewModelEvent = WebViewModelEvent()
if (!TextUtils.isEmpty(params)) {
val decodeParam: String =
EncodeUtils.decode(params!!.replace(" ", "+"))
LogWebViewUtils.e("PkWebView decodeParam:$decodeParam")
if (TextUtils.equals("/jumpToWhere", path)) {
val newHybridModel: NewHybridModel = GsonUtils.fromJson(
decodeParam,
NewHybridModel::class.java
)
webViewModelEvent.newHybridModel = newHybridModel
} else {
val webViewModel: WebViewModel =
GsonUtils.fromJson(decodeParam, WebViewModel::class.java)
webViewModelEvent.webViewModel = webViewModel
}
}
return webViewModelEvent
}
}
关于我
- 简书(www.jianshu.com/u/3ff32f5ae…)
- 我的GitHub地址(github.com/Peakmain)