专栏首页大话swiftkotlin构建MVVM应用之双向数据绑定

kotlin构建MVVM应用之双向数据绑定

我们在构建MVVM应用的时候数据时双向流动的,比如:用户输入了数据,那么我们的model层的数据也要自动跟着更新或者我们校验了数据,是图层也要给用户反馈;网络请求完成,我们的视图层的数据也要跟着更新。

定义model层

package com.xiangshike.live.model
 
 
import androidx.databinding.ObservableField
 
 
data class UserModel(
 
    val username: ObservableField<String> = ObservableField(""),
 
    val password: ObservableField<String> = ObservableField("")
 
) {
 
 override fun toString(): String {
 
        return "UserModel(username=
 }
 
}

ObservableField表示这是一个可以被观察的String类型数据,我们在用户的model层定义了两个可以被观察的变量,我们可以和视图进行双向绑定

Activity

package com.xiangshike.live
 


 
import android.util.Log
 
import com.xiangshike.live.base.BaseActivity
 
import com.xiangshike.live.databinding.ActivityMainBinding
 
import com.xiangshike.live.model.UserModel
 
import kotlinx.android.synthetic.main.activity_main.*
 


 
class MainActivity : BaseActivity<ActivityMainBinding>() {
 
 private val mUserModel: UserModel by lazy { UserModel() }
 
 override fun getLayoutId(): Int = R.layout.activity_main
 
 override fun initData() {
 
        mDataBind.userModel = mUserModel
 
 }
 


 
 override fun initView() {
 
        loginBtn.setOnClickListener {
 
            login()
 
 }
 
 }
 


 
 private fun login() {
 
        val username = mUserModel.username.get().toString()
 
        val password: String = mUserModel.password.get().toString()
 
        username.isEmpty().let {
 
 when (it) {
 
 true -> usernameLayout.error = "用户名不可以为空"
 
 false -> usernameLayout.isErrorEnabled = false
 
 }
 
 }
 
        password.isEmpty().also {
 
 when (it) {
 
 true -> passwordLayout.error = "密码不可以为空"
 
 false -> passwordLayout.isErrorEnabled = false
 
 }
 
 }
 


 
        Log.d("mUserModel", "username:
 }
 
}
 

首先,我们给登录按钮增加点击事件

override fun initView() {
 
        loginBtn.setOnClickListener {
 
            login()
 
 }
 
 }
 

其次,我们定义了login的方法,在这里我们实现了视图和model的双向绑定

 private fun login() {
 
        val username = mUserModel.username.get().toString()
 
        val password: String = mUserModel.password.get().toString()
 
        username.isEmpty().let {
 
 when (it) {
 
 true -> usernameLayout.error = "用户名不可以为空"
 
 false -> usernameLayout.isErrorEnabled = false
 
 }
 
 }
 
        password.isEmpty().also {
 
 when (it) {
 
 true -> passwordLayout.error = "密码不可以为空"
 
 false -> passwordLayout.isErrorEnabled = false
 
 }
 
 }
 


 
        Log.d("mUserModel", "username:
 }
 

view层

<?xml version="1.0" encoding="utf-8"?>
 
<layout xmlns:android="http://schemas.android.com/apk/res/android"
 
 xmlns:app="http://schemas.android.com/apk/res-auto">
 


 
 <data>
 


 
 <variable
 
 name="userModel"
 
 type="com.xiangshike.live.model.UserModel" />
 
 </data>
 


 
 <LinearLayout
 
 android:layout_width="match_parent"
 
 android:layout_height="match_parent"
 
 android:orientation="vertical">
 


 
 <com.google.android.material.textfield.TextInputLayout
 
 android:id="@+id/usernameLayout"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:layout_marginTop="66dp">
 


 
 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@+id/username"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/username"
 
 android:singleLine="true"
 
 android:text="@={userModel.username}" />
 
 </com.google.android.material.textfield.TextInputLayout>
 


 
 <com.google.android.material.textfield.TextInputLayout
 
 android:id="@+id/passwordLayout"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:layout_marginTop="66dp"
 
 app:passwordToggleEnabled="true">
 


 
 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@+id/password"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/password"
 
 android:inputType="textPassword"
 
 android:text="@={userModel.password}" />
 
 </com.google.android.material.textfield.TextInputLayout>
 


 
 <Button
 
 android:id="@+id/loginBtn"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:text="@string/login" />
 
 </LinearLayout>
 


 


 
</layout>
 

我们的密码框和model双向绑定

@={userModel.username} 实现的双向绑定,model<=>view的双向数据流通

 <com.google.android.material.textfield.TextInputEditText
 
 android:id="@+id/username"
 
 android:layout_width="match_parent"
 
 android:layout_height="wrap_content"
 
 android:hint="@string/username"
 
 android:singleLine="true"
 
 android:text="@={userModel.username}" />
 

我们输入内容,点击登录,查看控制台输出

2020-04-14 11:28:00.886 10583-10583/? D/mUserModel: username:1111  password:11111

本文分享自微信公众号 - 大话swift(gh_ca2266b7cab0),作者:寒云

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • kotlin如何使用MVVM的开发模式

    互联网开发模式经历了MVC、MVP。Android本身的开发模式为MVC,前些年MVP大行其道,这两年MVVM逐渐开始流行,最近准备用kotlin开发一个项目,...

    大话swift
  • Android layer实现圆角 阴影

    在drawable的那个layer布局xml中采用item的方式将各个图形控制分开,依照层级堆叠

    大话swift
  • Android 集成百度地图那些事

    implementation files('libs/BaiduLBS_Android.jar')

    大话swift
  • Android WebView实现顶部进度条

    项目中用到WebView加上进度条放在顶部,让用户知道加载进度情况,可以提高用户体验:

    砸漏
  • Android-如何显示版本号并制作3秒跳转页

    大家好,我是 Vic,今天给大家带来Android-如何显示版本号并制作3秒跳转页的概述,希望你们喜欢

    达达前端
  • Android实现简单的城市列表功能

    砸漏
  • achartengine之折线图

    问题在文章的最后,大致说来就是折线图,如果点的个数大于3个的时候,不是所有的点都显示对应的值的,这是为什么呢,本来以为是小问题,但两天了还没找到原因) 将前...

    xiangzhihong
  • 使用Android studio3.6的java api方式调用opencv

    (2)File- New- Import Module,然后选择自己的java-opencv的相对应路径,比如,D:\Android\OpenCV-androi...

    砸漏
  • 用ESP8266+android,制作自己的WIFI小车(Android 软件)用ESP8266+android,制作自己的WIFI小车(ESP8266篇)

    先说一下这篇文章里面的内容:TCP 客户端, 自定义对话框, 自定义按钮, ProgressBar竖直显示, 重力感应传感器,手机返回键新开启界面的问题(返回上...

    杨奉武
  • Android之TCP服务器编程android 之TCP客户端编程

    推荐一个学java或C++的网站http://www.weixueyuan.net/,本来想自己学了总结出来再写博客,现在没时间,打字太慢!!!!,又想让这好东...

    杨奉武

扫码关注云+社区

领取腾讯云代金券