Android Jetpack 学习之旅--> Data Binding 的使用
Posted Kevin-Dev
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Jetpack 学习之旅--> Data Binding 的使用相关的知识,希望对你有一定的参考价值。
介绍
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.LoginModel
。name
属性指明变量的名字,方便布局中使用。 -
import
data
中使用,需要使用静态方法和静态常量,如需要使用View.Visble
属性的时候,则需导入<import type="android.view.View"/>
。type
属性指明类的路径,如果两个import
标签导入的类名相同,则可以使用alias
属性声明别名,使用的时候直接使用别名即可。 -
include
View
标签中使用,作用同普通布局中的include
一样,需要使用bind:<参数名>
传递参数
- 生成绑定类
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
小结
以上是关于Android Jetpack 学习之旅--> Data Binding 的使用的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack 学习之旅--> Data Binding 的使用
Android Jetpack学习之旅--> Navigation 的使用
Android Jetpack 学习之旅--> ViewModel & LiveData 的使用
Android Jetpack 学习之旅--> Room 的使用