当前位置:网站首页>学习MVVM笔记(一)
学习MVVM笔记(一)
2022-07-05 04:06:00 【一禅-小和尚】
MVVM
model :数据层,包含数据实体和对数据实体的操作
View :界面层,对应Activity XML view 负责数据显示以及用户交互
ViewModel :关联层 将model 和view 进行绑定,model或者View 更改时,实时刷新对方
注意:
1.View只做和UI相关的工作,不涉及任何业务逻辑,不涉及操作数据,不处理数据。UI和数据严格的分开
2.ViewModel只做和业务逻辑相关的工作,不涉及任何和UI相关的操作,不持有控件引用,不更新UI。
DataBinding 是谷歌官方推荐的一个库,DataBinding 库来写声明的layouts文件,可以用最少的代码来绑定你的app逻辑和layouts文件 ,DataBinding是一个support库
(1)搭建环境
在app的build.gradle文件中添加
android {
.... dataBinding {
enabled = true } }
(2)编写layout文件
起始标签是layout,接下来是data元素一个view元素,这个view元素就是没有使用DataBinding的layout文件的根元素
在data内描述一个name的变量属性,使其可以在layout中使用,type为绑定的data对象
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.example.mvvmdemo.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_name"
android:text="@{user.mUserName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_age"
android:text='@{
user.mUserage + ""}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
data对象:
package com.example.mvvmdemo;
public class User {
public final String mUserName;
public final int mUserage;
public User(String userName, int userAge) {
this.mUserName = userName;
mUserage = userAge;
}
}
(3)Binding数据
默认情况下,一个Binding类会基于layout文件的名称而产生,将其转换成(首字母大写的命名规范,并加Binding后缀) ,上述的layout文件是activity_main.xml ,因此生成的类名是ActivityMainBinding。此类包含从layout属性到layout的views中的所有bindings(包括user变量) ,而且还知道怎么给Binding表达式分配值,创建bindings的最简单的inflating(layout文件和Activity/Fragment的链接)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
User user = new User("haha" , 22);
binding.setUser(user);
}
}
**如果在ListView 或者RecyclerView adapter使用DataBinding时,会使用
**
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); //or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
还需要注意的是:如果将User类中的变量改成私有的会报错的。
Found data binding errors. ****/ data binding error ****msg:Could not find accessor demo.com.databindingdemo.User.mUserName
(4)事件处理
数据绑定允许编写表达式来处理view分派的事件,事件属性名字取决于监听器方法名字。
public class MyHandler {
public void myOnClick(View view){
Toast.makeText(view.getContext(),"hello",Toast.LENGTH_SHORT).show();
}
public boolean myOnLongClick(View view){
Toast.makeText(view.getContext(),"hello world",Toast.LENGTH_SHORT).show();
return true;
}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.heyy.databingexample.MyHandler"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试事件绑定"
android:onClick="@{handlers::myOnClick}"
android:onLongClick="@{handlers::myOnLongClick}"/>
</LinearLayout>
</layout>
(5)深入DataBinding用法
import :零个或者多个import元素可能在data元素中使用,这些只用在你的layout文件中添加引用
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.example.mvvmdemo.User" />
<import type="android.view.View"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:text="@{user.mUserName}"
android:visibility="@{user.mUserage == 22 ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_age"
android:text='@{
user.mUserage + ""}'/>
当类名有冲突时,可以使用alias重新命名
<import type="android.view.View"
alias="test"/>
android:visibility="@{user.mUserage == 22 ? test.VISIBLE : test.GONE}"
导入的类型还可以在表达式中使用static属性和用法
public class StringUtls {
public static String translateStr(String str){
return str+"haha";
}
}
<import type="com.example.mvvmdemo.StringUtls"/>
android:text="@{StringUtls.translateStr(user.mUserName)}"
(6)Data对象
DataBinging 允许我们创建可观察的对象,字段和集合,当我们数据发生改变时,要通知其他的对象就可以使用DataBinding
Observable对象
实现android.databinding.Observable接口的类可以允许附加一个监听器到Bound对象,以便监听对象上的所有属性的变化。
一个BaseObervabke的基类为实现监听器注册机制而创建。
public void setmUserName(String mUserName) {
this.mUserName = mUserName;
notifyPropertyChanged(BR.user);
}
Observable 集合
Oberservable集合允许控件访问这些data对象,ObservableArraMap 用于键是引用类型,如string
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("name", "Jack"); user.put("age", 17);
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/> </data>
<TextView
android:text='@{
user["name"]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{
String.valueOf(1 + (Integer)user["age"])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Observable 字段
ObservableFields是包含具有单个字段的Observable对象。
<data>
<variable
name="itemViewModel"
type="com.autoai.project.home.viewmodel.AppItemViewModel" />
</data>
使用
android:text="@{itemViewModel.appTitle}"
类
public class AppItemViewModel {
public ObservableField<String> appTitle = new ObservableField<>();
}
边栏推荐
- Open graph protocol
- provide/inject
- The development of mobile IM based on TCP still needs to keep the heartbeat alive
- 如何实现实时音视频聊天功能
- Rust区块琏开发——签名加密与私钥公钥
- PlasticSCM 企业版Crack
- Threejs realizes rain, snow, overcast, sunny, flame
- Redis source code analysis: redis cluster
- How to use jedis of redis
- About the project error reporting solution of mpaas Pb access mode adapting to 64 bit CPU architecture
猜你喜欢
MindFusion. Virtual Keyboard for WPF
kubernetes集群之调度系统
Threejs Internet of things, 3D visualization of farm (III) model display, track controller setting, model moving along the route, model adding frame, custom style display label, click the model to obt
Is "golden nine and silver ten" the best time to find a job? Not necessarily
C # use awaiter
Special Edition: spreadjs v15.1 vs spreadjs v15.0
Threejs implements labels and displays labels with custom styles
面试字节,过关斩将直接干到 3 面,结果找了个架构师来吊打我?
输入的查询SQL语句,是如何执行的?
Plasticscm enterprise crack
随机推荐
Redis source code analysis: redis cluster
输入的查询SQL语句,是如何执行的?
Analysis of dagger2 principle
Un réveil de l'application B devrait être rapide
How is the entered query SQL statement executed?
Judge whether the stack order is reasonable according to the stack order
UI自动化测试从此告别手动下载浏览器驱动
DMX parameter exploration of grandma2 onpc 3.1.2.5
Clickhouse synchronization MySQL (based on materialization engine)
Threejs implements labels and displays labels with custom styles
Threejs realizes the drawing of the earth, geographical location annotation, longitude and latitude conversion of world coordinates threejs coordinates
面试汇总:这是一份全面&详细的Android面试指南
陇原战“疫“2021网络安全大赛 Web EasyJaba
测试开发是什么?为什么现在那么多公司都要招聘测试开发?
Uni app common functions /api
As soon as I write the code, President Wang talks with me about the pattern all day
Threejs Internet of things, 3D visualization of farms (I)
Threejs Internet of things, 3D visualization of farms (II)
Is "golden nine and silver ten" the best time to find a job? Not necessarily
为什么百度、阿里这些大厂宁愿花25K招聘应届生,也不愿涨薪5K留住老员工?