从0到1打造一款安卓app之11-集成腾讯浏览服务TBS并处理fragment返回键事件

264 阅读2分钟

从0到1打造一款安卓app之11-集成腾讯浏览服务TBS并处理fragment返回键事件

1.处理fragment返回键事件

OnBackPressedDispatcher提供了一个方法,可以有生命周期感知 的 OnBackPressedCallback

OnBackPressedDispatcher类的方法
public void addCallback(@NonNull LifecycleOwner owner,
        @NonNull OnBackPressedCallback onBackPressedCallback) {
    Lifecycle lifecycle = owner.getLifecycle();
    if (lifecycle.getCurrentState() == Lifecycle.State.DESTROYED) {
        return;
    }

    onBackPressedCallback.addCancellable(
            new LifecycleOnBackPressedCancellable(lifecycle, onBackPressedCallback));
}
private class LifecycleOnBackPressedCancellable implements LifecycleEventObserver,
        Cancellable {
    private final Lifecycle mLifecycle;
    private final OnBackPressedCallback mOnBackPressedCallback;

    @Nullable
    private Cancellable mCurrentCancellable;

    LifecycleOnBackPressedCancellable(@NonNull Lifecycle lifecycle,
            @NonNull OnBackPressedCallback onBackPressedCallback) {
        mLifecycle = lifecycle;
        mOnBackPressedCallback = onBackPressedCallback;
        lifecycle.addObserver(this);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        if (event == Lifecycle.Event.ON_START) {
            mCurrentCancellable = addCancellableCallback(mOnBackPressedCallback);
        } else if (event == Lifecycle.Event.ON_STOP) {
            // Should always be non-null
            if (mCurrentCancellable != null) {
                mCurrentCancellable.cancel();
            }
        } else if (event == Lifecycle.Event.ON_DESTROY) {
            cancel();
        }
    }

    @Override
    public void cancel() {
        mLifecycle.removeObserver(this);
        mOnBackPressedCallback.removeCancellable(this);
        if (mCurrentCancellable != null) {
            mCurrentCancellable.cancel();
            mCurrentCancellable = null;
        }
    }
}

定义BaseFragment用于添加OnBackPressedCallback

open class BaseFragment : Fragment() {

    fun addOnBackPressed(owner: LifecycleOwner? = null, onBackPressed: () -> Boolean): OnBackPressedCallback {
        LogUtils.d(this::class.java.simpleName, "addOnBackPressed")
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                LogUtils.d(this@BaseFragment::class.java.simpleName, "handleOnBackPressed")
                if (!onBackPressed()) {
                    isEnabled = false
                    requireActivity().onBackPressedDispatcher.onBackPressed()
                    isEnabled = true
                }
            }
        }
        if (owner != null) {
            requireActivity().onBackPressedDispatcher.addCallback(owner, callback)
        } else {
            requireActivity().onBackPressedDispatcher.addCallback(callback)
        }
        return callback
    }

    open var overrideOnBackPressed: Boolean = false
    open fun onBackPressed(): Boolean {
        return false
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        LogUtils.d(this::class.java.simpleName, "onViewCreated")
        if (overrideOnBackPressed) {
            addOnBackPressed(viewLifecycleOwner) {
                return@addOnBackPressed onBackPressed()
            }
        }
    }
}

2.集成腾讯浏览服务TBS

集成步骤请查看官网

腾讯浏览服务 (tencent.com)

定义BaseWebFragment配置webView

1.处理返回键事件

2.配置基本的 WebSettings

3.设置webViewClient和webChromeClient

4.显示标题

5.处理加载进度变化,显示进度条和转圈

const val ORIGINAL_URL_FLAG = "original_url_flag"

open class BaseWebViewFragment : BaseFragment() {

    protected open var dataBinding: FragmentBaseWebViewBinding? by autoCleared()
    protected open var originalUrl: String = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            originalUrl = it.getString(ORIGINAL_URL_FLAG, "")
        }
    }
   
   //处理返回键事件
    override var overrideOnBackPressed = true
    override fun onBackPressed(): Boolean {
        return dataBinding?.baseX5WebView?.run {
           //判断是否可以返回
            if (!canGoBack()) {
                return@run false
            }
            goBack()
            return@run true
        } ?: false
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        dataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_base_web_view, container, false)
        return dataBinding?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initWebView()
        dataBinding?.baseWebViewSwipeRefreshLayout?.setColorSchemeResources(
            R.color.blue,
            android.R.color.holo_red_light,
            android.R.color.holo_green_light
        )

        originalUrl.let {
            if (it.isEmpty()) return
            dataBinding?.baseX5WebView?.loadUrl(originalUrl)
        }

    }

    private fun initWebView() {
       //配置基本的 WebSettings
        dataBinding?.baseX5WebView?.settings?.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            loadsImagesAutomatically = true
            useWideViewPort = true
            loadWithOverviewMode = true
        }

      //设置webViewClient和webChromeClient
        dataBinding?.baseX5WebView?.apply {
            webViewClient = _webViewClient
            webChromeClient = _webChromeClient
        }
    }

    private val _webViewClient = object : WebViewClient() {

        override fun onPageStarted(webView: WebView?, url: String?, bitmap: Bitmap?) {
            super.onPageStarted(webView, url, bitmap)
            onProgressChanged(0)
        }

        override fun onPageFinished(webView: WebView?, url: String?) {
            super.onPageFinished(webView, url)
            onProgressChanged(100)
        }
    }

    private val _webChromeClient = object : WebChromeClient() {
        override fun onProgressChanged(webView: WebView?, progress: Int) {
            super.onProgressChanged(webView, progress)
            onProgressChanged(progress)
        }

        override fun onReceivedTitle(p0: WebView?, p1: String?) {
            super.onReceivedTitle(p0, p1)
            //显示标题
            dataBinding?.tvWebViewTitle?.text = p1
        }
    }

   //处理加载进度变化,显示进度条和转圈
    private fun onProgressChanged(progress: Int) {
        val isFinished = progress >= 100

        dataBinding?.webViewProgressBar?.apply {
            this.progress = progress
            val v = if (isFinished) View.GONE else View.VISIBLE
            if (visibility != v)
                visibility = v
        }

        dataBinding?.baseWebViewSwipeRefreshLayout?.apply {
            if (isEnabled != !isFinished) isEnabled = !isFinished
            if (isRefreshing != !isFinished) isRefreshing = !isFinished
        }
    }


    companion object {
        @JvmStatic
        fun newInstance(url: String) =
            BaseWebViewFragment().apply {
                arguments = Bundle().apply {
                    //通过Bundle设置参数
                    putString(ORIGINAL_URL_FLAG, url)
                }
            }
    }
}