mvvm的dataBinding无法自动生成binding类的解决办法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mvvm的dataBinding无法自动生成binding类的解决办法相关的知识,希望对你有一定的参考价值。
参考技术A https://blog.csdn.net/huangxin388/article/details/774256781、
保证修改gradle的位置正确,在android标签下。
2、
3、
修改完成后别忘记点右上角Sync Now。
4、
我们在xml中添加标签的时候习惯性的第一个字母大写,其实添加的layout标签是<layout></layout>小写的
6、
binding类是根据xml布局文件的名字生成的
activity_main.xml->ActivityMainBinding
activity_item.xml->ActivityItemBinding
splash_test.xml->SplashTestBinding
依此类推
如果你的布局文件名字和书上不一致,生成的binding类自然不一样,因此不要盲目使用书上的binding类,找不到的。
7、
如果还没有出现binding类只好放大招了,重启AS,然后将项目运行一下(只修改gradle文件和xml文件后是不会出现错误的)。待gradle重新构建应该就会出现了
8、
Build->make project
9、
同一个ViewModel类,在不同的xml文件中被多次使用
更改name的值为viewModel1
<data>
<import type="android.view.View" />
<variable
name="viewModel1"
type="main.com.pwj.mvvmtest.weather.viewmode.QueryWeatherViewModel" />
</data>
10、重启大法有时候确实管用。。。
我是通过第8和9的方法解决了,主要原因是多个xml使用了ViewModel
具体问题具体分析。肯定跑不出这个10中原因
网友典型问题:
A:
维护项目,要新增页面,因为之前没用过,所以直接复制了其他页面的布局文件修改。发现找不到Binding类,一直没给我生成。后面删除布局文件的时候生成了。。估计是必须要重新创建才会生成。也许和AS及databinding版本有关。
B:
如果Build.gradle和Layout文件配置正确,仍无法生成ViewDataBinding类。
经测试,Gradle的sync无效,clean project无效,invalidate and restart无效,但是Build->Rebuild Project生效了。
还不行的话,使用ViewDataBinding抽象类的setVariable方法,也可以生效。
AS版本:3.1.3
gradle版本:3.1.3
Android进阶之MVVM+DataBinding框架模式(更新中)
MVVM框架
MVVM框架实现了数据和视图的绑定(DataBinding),当数据变化时,视图会自动更新;反之,当视图变化时,数据会自动是新
MVVM模式与MVP模式一样,也将应用分为三层,并且各个对应的层的职责相似:
- Model层,主要负责数据的提供。Model层提供业务逻辑的数据结构(比如,实体类),提供数据的获取(比如,从本地数据库或者远程网络获取数据),提供数据的存储
- View层,主要负责界面的显示。View层不涉及任何的业务逻辑处理,它持有ViewModel层的引用,当需要进行业务逻辑处理时通知ViewModel层
- ViewModel层,主要负责业务逻辑的处理。ViewModel层不涉及任何的视图操作。通过官方提供的Data Binding库,View层和ViewModel层中的数据可以实现绑定,ViewModel层中数据的变化可以自动通知View层进行更新,因此ViewModel层不需要持有View层的引用。ViewModel层可以看作是View层的数据模型和Presenter层的结合
MVVM模式与MVP模式最大的区别在于:ViewModel层不持有View层的引用。这样进一步降低了耦合,View层代码的改变不会影响ViewModel层
MVVM模式相对于MVP模式主要有如下优点:
- 进一步降低了耦合。ViewModel层不持有View层的引用,当View层发生改变时,只要View层绑定的数据不变,那么ViewModel层就不需要改变。而在MVP模式下,当View层发生改变时,操作视图的接口就要进行相应的改变,那么Presenter层就需要修改了
- 不用再编写很多样板代码。通过官方的Data Binding库,UI和数据之间可以实现绑定,不用再编写大量的findViewById()和操作视图的代码了。总之,Activity/Fragment的代码可以做到相当简洁
一、DataBinding使用步骤:
- 启用DataBinding
- 修改布局文件为DataBinding布局
- 数据绑定
二、使用MVVM框架步骤:
- 提供View、ViewModel以及Model三层
- 将布局修改为DataBinding布局
- View与ViewModel之间通过DataBinding进行通信
- 获取数据并展示在界面上
MVVM的全称是Model(模型)–View(视图)–ViewModel(视图模型):
MVVM可以算是MVP的升级版,将Presenter改为了VIewModel。关键在于View和Model的双向绑定,当View有用户输入后,ViewModel通知Model更新数据,同理Model数据更新后,ViewModel通知View更新
MVVM的优势如下:
1、View和Model双向绑定,一方的改变都会影响一方,开发者不用再去手动修改UI的数据
2、不需要findViewById也不需要butterknife,不需要拿到具体的View去设置数据绑定监听器等等,这些都可以用DataBinding完成
3、View和Model的双向绑定是支持生命周期检测的,不会担心页面销毁了还有回调发生,这个由lifeCycle完成
4、不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的View和Presenter接口。项目结构更加低耦合
什么是databinding
DataBinding是谷歌官方发布的一个框架,顾名思义即为数据绑定,是MVVM模式在Android上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰
接下来进入正题
首先要启用databinding:
启用DataBinding的方法是在对应Model的build.gradle文件里加入以下代码,同步后就能引入对DataBinding的支持
android
...
dataBinding
enabled = true
下面具体介绍下MVVM框架:
1、VM层:
这里根据MVVMActivity的布局文件activity_mvvmpattern,介绍下Data Binding:
Data Binding对使用的环境还是有一定要求的:Android Studio版本在1.3以上,gradle的版本要在1.5.0-alpha1以上。
需要在Android SDK manager中下载Android Support repository
然后在对应的Module的build.gradle中添加:
android
....
dataBinding
enabled =true
然后使用databinding语法对xml进行数据绑定,我们将Click事件、输出结果都绑定到VM上
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<!--使用import来导入需要用的包-->
<import type="android.view.View" />
<!--使用关键字variable来声明一个变量,name为变量名,type为指向的对象,可以是类名也可以是类名的别名-->
<variable
name="userViewModel"
type="com.mvvm.model.mvvm.viewmodel.MVVMDataViewModel" />
<variable
name="handlers"
type="com.mvvm.model.mvvm.view.MVVMActivity" />
<!--对于基本类型,可以像java代码一样不用去导入包,直接使用-->
<variable
name="data"
type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/btnMVVM"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@handlers.onClickLoadData"
android:text="点击请求数据" />
<Button
android:id="@+id/btnToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@handlers.onClickShowToastName"
android:text="点击请求数据并Toast提示" />
<!--使用变量-->
<TextView
android:id="@+id/tvData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@userViewModel.data" />
</LinearLayout>
</layout>
在data中定义的variable(变量)节点,name属性表示变量的名称,type表示这个变量的类型,实例就是我们实体类的位置,当然,这里你也可以换这种方式:
<data>
<import type="android.view.View" />
<variable
name="userViewModel"
type="com.mvvm.model.mvvm.viewmodel.MVVMDataViewModel" />
</data>
BaseObservable,observable:观察者
还是MVVMDataViewModel类来举例,BaseObservable提供了两个刷新UI的方法,分别是notifyPropertyChanged() 和 notifyChange()
1.notifyPropertyChanged();只会刷新属于它的UI,就如代码,他只会更新name
2.notifyChange();会刷新所有UI
Bean类继承BaseObservable
notifyPropertyChanged()需要传入一个int类型的参数,这个参数就是int fieldId,指的就是那个形参name
Bindable用于将数据绑定到视图
VM层具体类:这里注意具体的属性需要加@Bindable,否则绑定无效
public class MVVMDataViewModel extends BaseObservable implements MVVMLoadDataCallback
private MVVMDataModel model;
public MVVMDataViewModel()
model = new MVVMDataModel();
/**
* 必须添加@Bindable注释
* @return
*/
@Bindable
public String getData()
return model.mData;
public void loadUserData()
model.requestData(this);
@Override
public void onSuccess()
notifyPropertyChanged(com.mvvm.model.BR.data);
@Override
public void onFailure()
选择你自己工程下的BR或者第三个BR
2、View层(MVVMActivity) 引入VM:
/**
* View层
*/
public class MVVMActivity extends AppCompatActivity
private MVVMDataViewModel userViewModel;
private TextView tvData;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
ActivityMvvmpatternBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_mvvmpattern);
userViewModel = new MVVMDataViewModel();
binding.setUserViewModel(userViewModel);
binding.setHandlers(this);
tvData = binding.tvData;
public void onClickShowToastName(View view)
Toast.makeText(this, tvData.getText().toString(), Toast.LENGTH_LONG).show();
public void onClickLoadData(View view)
userViewModel.loadUserData();
3、Model层:
用来进行具体的数据请求操作
/**
* Model层
*/
public class MVVMDataModel
public String mData;
public MVVMDataModel()
this.mData = "初始数据";
public void requestData(MVVMLoadDataCallback callback)
this.mData = "数据请求成功";
callback.onSuccess();
MVVM虽然有这些个优点,但使用起来的坑也是不少的,所以日前MVVM框架在实际开发中应用并不是很多,主要以MVP框架开发为主
最后提供下github源码,供大家参考:testMVVM
以上是关于mvvm的dataBinding无法自动生成binding类的解决办法的主要内容,如果未能解决你的问题,请参考以下文章
Android进阶之MVVM+DataBinding框架模式(更新中)
Android mvvm架构demo(DataBinding+LiveData+ViewModel+ Repository)
Android DataBinding库(MVVM设计模式)