在Kotlin中使用MVVM实现双向数据绑定WebView [英] Implementing two way data-binding WebView using MVVM in Kotlin

查看:480
本文介绍了在Kotlin中使用MVVM实现双向数据绑定WebView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在所有应用程序中实现MVVM,对此我还很陌生,所以我想通过ViewModel加载Webview,但是我不知道如何做到这一点的最佳方法,如果还有加载我的Web视图时显示的进度条.

I am trying to implement MVVM in all my app and I am very new to this, so I want to load a webview through my ViewModel, but I don't know the best way how to do this, if also has a progress bar that shows up when my web view is loading.

代码如下:

    class NewWebViewFragment : Fragment() {

    private lateinit var viewModel: NewWebViewViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        val binding: FragmentWebViewBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_web_view, container, false)

        val webViewModelo = ViewModelProviders.of(this).get(NewWebViewViewModel::class.java)

        binding.webViewModel = webViewModelo
        binding.lifecycleOwner = this


        return binding.root
    }

}

现在,我的ViewModel:

Now my ViewModel:

class NewWebViewViewModel : ViewModel() {

//Implement in MVVM

private fun showWebView(webView: WebView, progressBar: ProgressBar) {

        webView.webViewClient = WebViewClient()
        webView.webChromeClient = WebChromeClient()

        val webSettings = webView.settings
        webSettings.javaScriptEnabled = true

        webView.loadUrl("https://brand.randombrand.com/en/")

        webView.webViewClient = object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                progressBar.visibility = View.VISIBLE
                super.onPageStarted(view, url, favicon)
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                progressBar.visibility = View.GONE
                super.onPageFinished(view, url)
            }
        }
    }
}

和我的XML:

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">


    <data>
        <variable
            name="webViewModel"
            type="com.example.navigations.viewmodel.webview.NewWebViewViewModel" />
    </data>

    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".fragments.WebViewFragment">


    <!-- TODO: Update blank fragment layout -->
        <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">


    </WebView>

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_gravity="center"/>


    </FrameLayout>
</layout>

我得到的错误是nullpointerexception,因为我传递的Web视图为null. 对实现此目标的最佳方法有何想法?

The Error I get is a nullpointerexception cause the webview i'm passing is null. Any thoughts of the best way to implement this?

推荐答案

我认为对您来说最好的选择是创建一个如下所示的绑定适配器:

I think the best option for you would be to create a Binding Adapter that will look like this:

@BindingAdapter("loadUrl")
fun WebView.setUrl(url: String) {
    this.loadUrl(url)
}

在您的ViewModel中,您可以通过Fragment参数接收数据(也许,如果它们来自另一个Fragment),或者只是从ViewModel中对其进行修改.

In your ViewModel you can either receive the data through Fragment arguments (maybe if they come from another Fragment) or just have them modified from the ViewModel.

在VM中,数据将是要加载的网址,例如val webViewUrl = MutableLiveData<String>().apply{ value = "initial url to be loaded .com" }.

In the VM the data will be the url to be loaded, maybe like val webViewUrl = MutableLiveData<String>().apply{ value = "initial url to be loaded .com" }.

在您的xml中:

<WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webView"
        app:loadUrl="@{viewModel.webViewUrl}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

是的,永远不要在ViewModel中做UI事情,例如实例化WebView或类似的东西.

And yes, you should never do UI stuff in the ViewModel, like instantiating a WebView, or something like that.

这篇关于在Kotlin中使用MVVM实现双向数据绑定WebView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆