在 Kotlin 中使用 MVVM 实现两种方式的数据绑定 WebView

     2023-05-07     34

关键词:

【中文标题】在 Kotlin 中使用 MVVM 实现两种方式的数据绑定 WebView【英文标题】:Implementing two way data-binding WebView using MVVM in Kotlin 【发布时间】:2020-05-08 13:18:00 【问题描述】:

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

代码如下:

    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:

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_
    android:layout_
    android:orientation="vertical"
    tools:context=".fragments.WebViewFragment">


    <!-- TODO: Update blank fragment layout -->
        <WebView
        android:layout_
        android:layout_
        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_
        android:layout_
        android:id="@+id/progressBar"
        android:layout_gravity="center"/>


    </FrameLayout>
</layout>

我得到的错误是nullpointerexception,因为我传递的 webview 为空。 对实现这一点的最佳方法有什么想法吗?

【问题讨论】:

【参考方案1】:

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

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

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

在 VM 中,数据将是要加载的 url,可能像 val webViewUrl = MutableLiveData&lt;String&gt;().apply value = "initial url to be loaded .com"

在你的 xml 中:

<WebView
        android:layout_
        android:layout_
        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 或类似的东西。

【讨论】:

您好,感谢您的评论!我应该在哪里实现这些 bindingAdapter?它们是否属于视图片段? 你可以创建一个只有绑定适配器的 Utils 类,我通常是这样做的:)【参考方案2】:

您可能不会在viewmodel 中使用webview

看https://developer.android.com/topic/libraries/data-binding/binding-adapters.html

MVVM 规则

第一条规则:视图中不应该有任何逻辑,根本没有!甚至不是一个简单的 if 条件。视图的所有逻辑都发生在 ViewModel 中。

第二条规则:为了响应事件,视图除了通过调用方法通知视图模型之外什么都不做。 View 不会将任何与视图相关的类传递给视图模型。

规则三:ViewModel 使用实时数据作为与视图通信的主要方式!

MVVM 的一个好处是 ViewModel 不需要知道任何关于 View 的信息,也不需要引用 View 类!相反,它使用反应式编程范式,因此 View 仍然可以观察数据并收到有关更改的通知。

规则四:视图可以在需要时调用视图模型。 ViewModel 可以为视图提供辅助方法。

【讨论】:

这是一个非常好的评论 :) 感谢您的洞察力和良好做法【参考方案3】:

我找到了加载 webView 的解决方案。这是我所做的:

 import android.webkit.WebView
import androidx.databinding.BindingAdapter

object Utilities 

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

1#为Utils创建了一个对象

<WebView
        android:layout_
        android:layout_
        android:id="@+id/webView"
            app:loadUrl="@webViewModel.webViewUrl"
            app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
            >

2 # 将 XML 更新为如下所示

3 # val webViewUrl = MutableLiveData().apply value = "https://google.com/en/"

将此添加到我的 ViewModel 类中

感谢 cmets 伙计们

【讨论】:

kotlin-反射

...,都能够调用它的任意一个方法和属性。常用API使用demoKotlin的反射需要集成org.jetbrains.kotlin:kotlin-reflect仓库,版本保持与kotlin一致。在Kotlin中,字节码对应的类是kotlin.reflect.KClass,因为Kotlin百分之百兼容Java,所以Kotlin中可以使用J... 查看详情

使用 MVVM 两种方式绑定到 AvalonEdit 文档文本

】使用MVVM两种方式绑定到AvalonEdit文档文本【英文标题】:TwoWayBindingtoAvalonEditDocumentTextusingMVVM【发布时间】:2013-09-2815:21:45【问题描述】:我想在我的MVVM应用程序中包含一个AvalonEditTextEditor控件。我需要的第一件事是能够绑定到... 查看详情

在 MVVM 架构中格式化来自改造 API 的嵌套 JSON 响应 - Kotlin

】在MVVM架构中格式化来自改造API的嵌套JSON响应-Kotlin【英文标题】:FormattingtheNestedJSONresponsefromretrofitAPIinMVVMArchitecture-Kotlin【发布时间】:2021-10-3021:30:18【问题描述】:我是kotlin和MVVM的新手,我已经解决这个问题一个星期了,即... 查看详情

在 Kotlin 中使用 BufferedReader 的最佳方式

】在Kotlin中使用BufferedReader的最佳方式【英文标题】:BestwaytouseBufferedReaderinKotlin【发布时间】:2017-04-2109:36:26【问题描述】:所以我刚刚开始使用KotlinforAndroid,并将我的AndroidJava代码转换为Kotlin。在一次转换中,我偶然发现了一... 查看详情

kotlin——数组

参考技术AKotlin为数组增加了一个Array类。为元素是基本类型的数组增加了XxxArray类(其中Xxx可以是Byte、Short、Int等基本类型)Kotlin自己提供了一套集合体系,Kotlin的集合体系抛弃了Java集合体系中的Queue集合,Kotlin集合体系中增加了... 查看详情

在 Kotlin 中使用接口的默认函数实现

】在Kotlin中使用接口的默认函数实现【英文标题】:UsingdefaultfunctionimplementationofinterfaceinKotlin【发布时间】:2021-12-1022:10:24【问题描述】:我有一个带有默认实现的Kotlin接口,例如:interfaceFoofunbar():Stringreturn"baz"在我尝试从Java实... 查看详情

kotlin用retrofit+okhttp+协程+livedata搭建mvvm(jetpack)来实现网络请求(网络数据json解析)显示在recyclerview(更新中)(代码片段)

文章目录一、效果图二、项目三、添加依赖包四、Retrofit封装类五、网络相关数据结构1、返回数据最外层包装2、单个数据结构六、定义协程api七、ViewModel层八、UI层调用九、旋转屏幕后数据的问题十、下载源码github地址一、效果... 查看详情

retrofit+kotlin+mvvm的网络请求框架的封装尝试(代码片段)

...请求框架的封装印象非常深刻,很喜欢这种Retrofit+Kotlin+协程的搭配使用。随后也在自己的项目里参考了这部分的代码。但随着代码的深入编写和功能的复杂,原来的框架已经无法满足我的使用了。原主要有如下的... 查看详情

retrofit+kotlin+mvvm的网络请求框架的封装尝试(代码片段)

...请求框架的封装印象非常深刻,很喜欢这种Retrofit+Kotlin+协程的搭配使用。随后也在自己的项目里参考了这部分的代码。但随着代码的深入编写和功能的复杂,原来的框架已经无法满足我的使用了。原主要有如下的... 查看详情

retrofit+kotlin+mvvm的网络请求框架的封装尝试(代码片段)

...请求框架的封装印象非常深刻,很喜欢这种Retrofit+Kotlin+协程的搭配使用。随后也在自己的项目里参考了这部分的代码。但随着代码的深入编写和功能的复杂,原来的框架已经无法满足我的使用了。原主要有如下的... 查看详情

使用retrofit+okhttp+livedata+协程的mvvm实现的网络请求框架(代码片段)

MVVM-Coroutine最近看到很多人在学习kotlin的时候,都有提及到协程,于是也就在网上跟着学习了一波。但是学过之后在什么用到呢?很多大牛开始用这个代替Rxjava或者线程来写MVVM框架了。更多关于个方面的原理问题࿰... 查看详情

使用retrofit+okhttp+livedata+协程的mvvm实现的网络请求框架(代码片段)

MVVM-Coroutine最近看到很多人在学习kotlin的时候,都有提及到协程,于是也就在网上跟着学习了一波。但是学过之后在什么用到呢?很多大牛开始用这个代替Rxjava或者线程来写MVVM框架了。更多关于个方面的原理问题࿰... 查看详情

Firebase:在 Kotlin/Java 中使用枚举字段的干净方式?

】Firebase:在Kotlin/Java中使用枚举字段的干净方式?【英文标题】:Firebase:cleanwayforusingenumfieldsinKotlin/Java?【发布时间】:2017-05-2919:44:54【问题描述】:我在firebase上的数据使用了许多具有字符串类型的字段,但实际上是枚举值(... 查看详情

kotlin数组

参考技术A数组在Kotlin中使用Array类来表示。下面巴拉一下Kotlin数组和Java数组的区别。Java中的数组通常的声明方式有以下两种:Kotlin的数组Array类中定义了get、set函数以及size(相当于java数组的length)的属性。什么?发生了什么?... 查看详情

在 Kotlin Multiplatform 中使用 Swift 协议默认实现

】在KotlinMultiplatform中使用Swift协议默认实现【英文标题】:UsingSwiftprotocoldefaultimplementationinKotlinMultiplatform【发布时间】:2021-04-3009:20:51【问题描述】:我尝试在KotlinMultiplatformXCFramework中使用Swift代码。我有一个扩展了该协议的默... 查看详情

在winform界面中使用devexpress的treelist实现节点过滤查询的两种方式(代码片段)

在我较早的一篇随笔《在DevExpress程序中使用TeeList控件以及节点查询的处理》中,介绍了在树形列表TreeList控件上面,利用SearchControl实现节点的模糊查询过滤操作,效果还是非常不错的,TreeList功能比较强大,界面也相对比微软... 查看详情

集群环境中使用redis实现分布式锁两种方式(代码片段)

...业务再次产生影响。分布式锁的实现有不少的方式,如:使用RDBM 查看详情

Kotlin 多平台:如何在没有 runBlocking 的情况下以阻塞方式启动协程

】Kotlin多平台:如何在没有runBlocking的情况下以阻塞方式启动协程【英文标题】:Kotlinmultiplatform:HowtostartcoroutineblockinglywithoutrunBlocking【发布时间】:2021-07-1717:22:39【问题描述】:我使用kotlinmultiplatform,它禁止在公共代码中使用ru... 查看详情