从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
集成步骤请查看官网
定义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)
}
}
}
}