WebView组件封装(三)——PkWebView的使用文档

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)