[Day15] Andoroid - Kotlin笔记: MVVM简介

MVVM由三项组成。
分别为(Model、View、ViewModel)

先来上MVVM架构图,方便下文介绍
文末会附上简单例子讲解。


View

  • View就是使用者看到的页面,
    xml以及我们负责显示xml数据的ActivityFragment都属於View层。

ViewModel

  • ViewModel负责接收View的需求,
    撰写逻辑与处理耗时工程,
    并向Model读出或写入资料。

  • ViewModel的生命周期:
    使用一个空的Fragment来进行生命周期管理。
    生命周期会与View共存,但和View互不影响。
    (更准确地来说,Activity在前台被销毁时,得到的是同个ViewModel
    Activity在後台被销毁时,就会是重建的ViewModel)
    详细介绍可以看这里

LiveData

  • 简单来说可以把它想成一个live(活着)的data。
    LiveData能够动态侦测到Data的改变。

  • 因为ViewModel是处理逻辑的地方,
    我们会把LiveData写在ViewModel中。

  • ViewModel跑完逻辑後,会将结果写入LiveData
    这时在View层,能够透过LiveDataobserve
    来取得更改後的资料,更新UI。


简单举例:

在登入页面按下登入按钮回到首页,首页要能判别状态为已登入,并展示使用者名称。

流程是这样走的:
资料以LoginResult这个Data Class做范例:

  1. Model层:
@JsonClass(generateAdapter = true)
data class LoginResult(

    @Json(name = "token")
    val token: Long,

    @Json(name = "userName")
    val userName: String? = null,

}

  1. View 层 (activity or fragment)

点击事件触发login的API,
call API这行为跟介面无关,是耗时流程,
因此会写在ViewModel

  fun initOnClick() {

      btn_login.setOnClickListener {
          viewModel.login()
      }

  }

同时在View层,透过观测LiveData
我们会接收已经拿到资料的loginResult
View层展示使用者的名字。
(View只做和UI有关的事)

  fun initObserver() {
        //activity用this, fragment用viewLifecycleOwner
        viewModel.loginResult.observe(this, { result ->
            tv_name.text = result.name
        })

  }

注:

  • viewLifecycleOwner是和onCreateView()、onDestroyView()绑在一起。
  • this则是与onCreate()、onDestroy()整个生命周期相关,会存活更久一些。

  1. ViewModel
    val loginResult: LiveData<LoginResult>
        get() = _loginResult

    fun login(account: String, password: String) {

        //送出post request的api参数
        val loginRequest = LoginRequest(
            account = account,
            password = password,
        )
        
        viewModelScope.launch {
            doNetwork(androidContext) {
              //这边做api逻辑,根据专案用volley、retrofit、okhttp,写法会不同
              //後面章节会再带到call api的部分。
                callLoginApi(loginRequest)
            }?.let { result ->

                //使用`postValue`来更新LiveData
                _loginResult.postValue(result)
            }
        })
    }

<<:  Day 18 - Tally String Times with Reduce

>>:  【把玩Azure DevOps】Day6 CI/CD从这里:开始之前的准备(范例介绍)

铁人赛 Day10-- PHP SQL基本语法(五) -- 帐密登入验证 & mysqli_query

前言 昨天知道了怎麽使用 SELECT 和 WHERE 之後,就要来实际做做看啦 (先附上整段程序码...

Day08,先介绍一下预备的家中环境

正文 动手做之前,今天先来简单介绍一下目前有限的家中环境规划,大概如图。 图片产自Draw.io 因...

day7 : logging集中(上)

昨天让kubernetes上的各项监控数据顺利的统一到grafana上,今天就来把服务的log统一集...

Log Agent - Fluent Bit Multiline Parsing

Fluent bit回顾 Log Agent - Fluent Bit 简介 Log Agent -...

从 IT 技术面细说 Search Console 的 27 组数字 KPI (20) :KPI 总表,从历史说起

在之前有说到为甚麽会有这张去 Monitor SEO 的数字总表,一开始只是要记录一个简单的事:平均...