MVVM出來有段時間了,MVVM由三部分構成 M:model數據 V:view視圖 VM:viewModel 視圖和數據雙向綁定(通過dataBinding實現);今天介紹下如何一步步實現,到快速使用。
1在項目的build 的android節點裏面 配置 dataBinding 的enabled爲true
android {
//開啓dataBinding
dataBinding{
enabled true
}
}
----------------------------------------------------------------MVVM基本使用-----------------------------------------------------------------------------------
2創建一個viewModel對象 (就是我們平時的bean對象)
public class Bean {
private String name;
private String password;
public Bean(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3在佈局使用laout標籤爲最外層標籤 (注意layout不要配置寬高屬性 不然build會報錯)
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--注意layout不要配置寬高屬性 -->
<!--data就是配置viewModel 即數據-->
<!--name 自定義 type爲viewModel 類的全類名-->
<data>
<variable
name="bean"
type="cn.zdh.mvvm.viewModel.Bean" />
</data>
<!--佈局代碼-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{`姓名: `+bean.name}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{`密碼: `+bean.password}" />
</LinearLayout>
</layout>
4 在activity代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
//使用系統API綁定佈局
//ActivityMainBinding是dataBinding build後生成的 名稱是根據你的佈局名稱+Binding
ActivityMainBinding mainBinding=DataBindingUtil.setContentView(this,R.layout.activity_main);
//設置數據
mainBinding.setBean(new Bean("張三", "123"));
}
}
這樣一個簡單的MVVM的demo就實現了
--------------------------------------------------------------------------數據驅動視圖變化-----------------------------------------------------------------------
1 MVVM是數據驅動UI,就是數據變了view就跟隨變化,那怎麼做到呢,修改下viewModel就可以
/**
* 實現 數據變化 視圖實時跟隨變化
* viewModel類 需要實現BaseObservable
* get 方法使用註解 @Bindable
* set 方法使用 notifyPropertyChanged(BR.對應屬性名);注意先build下
*/
public class Bean extends BaseObservable {
private String name;
private String password;
public Bean(String name, String password) {
this.name = name;
this.password = password;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
notifyPropertyChanged(BR.password);
}
}
2 在activity我們用代碼模擬數據變化
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
//使用系統API綁定佈局
//ActivityMainBinding是dataBinding build後生成的 名稱是根據你的佈局名稱+Binding
ActivityMainBinding mainBinding=DataBindingUtil.setContentView(this,R.layout.activity_main);
//設置數據
final Bean bean = new Bean("張三", "123");
mainBinding.setBean(bean);
//代碼設置5s後修改數據,看UI是否跟隨變化
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
bean.setName("李四");
bean.setPassword("0000");
}
}, 5000);
}
}
這樣就實現數據驅動視圖變化了。
--------------------------------------------------------------自定義屬性實現imageView 設置圖片----------------------------------------------------------
還是在viewModle裏面使用註解 @BindingAdapter(bind:自定義屬性名);注意方法需要 static修飾
/**
* 實現 數據變化 視圖實時跟隨變化
* viewModel類 需要實現BaseObservable
* get 方法使用註解 @Bindable
* set 方法使用 notifyPropertyChanged(BR.對應屬性名);注意先build下
*/
public class Bean extends BaseObservable {
private String name;
private String password;
//自定義屬性
private String phone;
@Bindable
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
notifyPropertyChanged(BR.phone);
}
public Bean(String name, String password, String phone) {
this.name = name;
this.password = password;
this.phone = phone;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
notifyPropertyChanged(BR.password);
}
/**
* 自定義屬性
* 使用註解 @BindingAdapter (如果括號使用bind: 括號裏面 bind: 是固定寫法 image是自定義屬性名)
* 建議直接寫屬性名,要不會有警告
* getImage 方法名自定義
*/
@BindingAdapter("phone")
public static void getImage(ImageView imageView,String url){
Glide.with(imageView.getContext()).load(url).into(imageView);
}
}
----------------------------------------------------------------------實現點擊---------------------------------------------------------------------------------------
在viewmodel 的Bean類添加下面方法
/**
* 點擊
* clickImage方法名可以自定義 ,必須和xml的onclick 引用的一致
* 方法參數必須有view
*/
public void clickImage(View view) {
Toast.makeText(view.getContext(), "點擊圖片", Toast.LENGTH_SHORT).show();
}
在xml添加如下
<!--使用自定義屬性以app開頭 + 自定義屬性名 ,沒有提示build下-->
<!--實現點擊效果只需要 在onClick屬性裏面 引用viewModel對應 定義的點擊方法名-->
<ImageView
android:onClick="@{bean.clickImage}"
android:layout_width="match_parent"
android:layout_height="100dp"
app:phone="@{bean.phone}"/>
//其他點擊類似用法就不舉例了。
源碼:
--------------------------------------------------------------mvvm如何使用插件輕鬆玩轉viewModel ------------------------------------------------------
下載插件databind generateAllFileSetter
//使用viewmodel繼承BaseObservable;Alt +insert(Windows快捷鍵) 選擇 DB getter and setter
//注意BR需要導包
//還不明白可以看使用詳情 https://github.com/njleonzhang/DataBindingGetterSetter
-----------------------------------------------------------MVVM的xml佈局插件使用---------------------------------------------------------------
下載插件Databinding Support
把光標放到頂層佈局,Alt+回車選擇convert to data binding layout
使用詳情 https://plugins.jetbrains.com/plugin/9271-databinding-support
//還有另外個插件也是針對xml的 https://github.com/idisfkj/databinding_autorun