【Android Jetpack 学习之旅】--> Data Binding 的使用

不断学习,做更好的自己!💪

视频号CSDN简书
欢迎打开微信,关注我的视频号:KevinDev点我点我

介绍

MVVM

MVVM(全称Model-View-ViewModel)同 MVC 和 MVP 一样,是逻辑分层解偶的模式(如果你还不了解 MVC 和 MVP ,建议提前了解一下)。
在这里插入图片描述
MVVM 的三要素

  • View 层:xml、Activity、Fragment、Adapter和View等
  • Model 层:数据源(本地数据和网络数据等)
  • ViewModel层:View层处理数据以及逻辑处理。

Data Binding

MVVM 和 Data Binding 是两个不同的概念,MVVM 是一种架构模式,而 Data Binding 是一个实现数据和 UI 绑定的框架,是构建 MVVM 模式的一个工具。

学习资料:
官方文档:Data Binding Library
谷歌实验室:官方教程
官方 Demo 地址:android-databinding

实战

1. 效果图
在这里插入图片描述
2. 在 app/build.gradle 文件添加:

android {
...
    dataBinding {
       enabled true
    }
}

3. 构建 LoginModel
LoginModel 主要负责登录逻辑的处理以及两个输入框内容改变的时候数据更新的处理。

class LoginModel constructor(name: String, pwd: String, context: Context) {
    val n = ObservableField<String>(name)
    val p = ObservableField<String>(pwd)
    var context: Context = context

    /**
     * 用户名改变回调的函数
     */
    fun onNameChanged(s: CharSequence) {
        n.set(s.toString())
    }

    /**
     * 密码改变的回调函数
     */
    fun onPwdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        p.set(s.toString())
    }

    fun login() {
        if (n.get().equals(BaseConstant.USER_NAME)
            && p.get().equals(BaseConstant.USER_PWD)
        ) {
            Toast.makeText(context, "账号密码正确", Toast.LENGTH_SHORT).show()
            val intent = Intent(context, MainActivity::class.java)
            context.startActivity(intent)
        }
    }
}

4. 创建布局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <!--需要的viewModel,通过mBinding.vm=mViewMode注入-->
        <variable
            name="model"
            type="com.hkt.navigationapp.model.LoginModel"/>

        <variable
            name="activity"
            type="androidx.fragment.app.FragmentActivity"/>

        <import type="android.view.View"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_cancel"
            style="@style/WrapWrap"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="20dp"
            android:layout_marginStart="20dp"
            android:textSize="@dimen/txt_big_size"
            android:drawableStart="@drawable/common_ic_back"
            android:paddingStart="10dp"
            android:paddingEnd="10dp"
            android:drawablePadding="10dp"
            android:text="Cancel"
            android:onClick="@{()-> activity.onBackPressed()}"
            android:textColor="@color/colorPrimary"/>

        <TextView
            android:id="@+id/tv_title"
            style="@style/WrapWrap.ConstraintCenter"
            app:layout_constraintHorizontal_bias="0.1"
            app:layout_constraintVertical_bias="0.1"
            android:text="Welcome back"
            android:textColor="@color/textPrimary"
            android:padding="20dp"
            android:textSize="28sp"
            android:textStyle="bold"
            tools:ignore="MissingConstraints"/>

        <EditText
            android:id="@+id/et_account"
            style="@style/CommonEditStyle"
            app:layout_constraintTop_toBottomOf="@+id/tv_title"
            app:layout_constraintBottom_toTopOf="@+id/et_pwd"
            app:layout_constraintVertical_chainStyle="packed"
            app:layout_constraintVertical_bias="0.3"
            android:hint="account"
            android:text="@{model.n.get()}"
            android:onTextChanged="@{(text, start, before, count)->model.onNameChanged(text)}"
            android:drawableStart="@drawable/common_ic_account"
            tools:ignore="MissingConstraints"/>

        <!-- TODO android:onTextChanged="@{(text, start, before, count)->model.onNameChanged(text)}"  -->

        <EditText
            android:id="@+id/et_pwd"
            style="@style/CommonEditStyle"
            app:layout_constraintTop_toBottomOf="@+id/et_account"
            app:layout_constraintBottom_toTopOf="@+id/btn_register"
            android:layout_marginTop="20dp"
            android:hint="password"
            android:drawableStart="@drawable/common_ic_pwd"
            android:inputType="textPassword"
            android:onClick="@{() -> model.login()}"
            android:text="@{model.p.get()}"
            android:onTextChanged="@{model::onPwdChanged}"
            tools:ignore="MissingConstraints,UnknownId,UnknownIdInLayout"/>


        <Button
            android:id="@+id/btn_login"
            style="@style/CommonButtonStyle"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.8"
            android:text="Sign in"
            android:enabled="@{(model.p.get().isEmpty()||model.n.get().isEmpty()) ? false : true}"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:ignore="MissingConstraints"/>


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

引入 Data Binding 之后的布局文件的使用方式会和以前的布局使用方式有很大的不同:

  • layout
    用作布局的根节点,只能包裹一个 View 标签,且不能包裹 merge 标签。

  • data
    Data Binding 的数据,只能存在一个 data 标签。

  • variable
    data 中使用,数据的变量标签,type 属性指明变量的类,如 com.hkt.navigationapp.model.LoginModelname 属性指明变量的名字,方便布局中使用。

  • import
    data 中使用,需要使用静态方法和静态常量,如需要使用 View.Visble 属性的时候,则需导入 <import type="android.view.View"/>type 属性指明类的路径,如果两个 import 标签导入的类名相同,则可以使用 alias 属性声明别名,使用的时候直接使用别名即可。

  • include
    View 标签中使用,作用同普通布局中的 include 一样,需要使用 bind:<参数名> 传递参数

  1. 生成绑定类
override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 1.Binding生成的方式一
        val binding: LoginFragmentBinding = DataBindingUtil.inflate(
            inflater
            , R.layout.login_fragment
            , container
            , false
        )

        onSubscribeUi(binding)
        
        val loginModel = LoginModel("","",context!!)
        binding.model = loginModel
        binding.activity = activity

        return binding.root
    }

小结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin-Dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值