MVC
- Model :數(shù)據(jù)操作
- View :視圖顯示
- Controller:交互和數(shù)據(jù)之間的控制業(yè)務(wù)
優(yōu)點(diǎn):代碼總量相對(duì)較少,適合功能簡(jiǎn)單的場(chǎng)景
缺點(diǎn):耦合度高,Activity定位尷尬,既是V又是C
MVP
- Model :數(shù)據(jù)操作
- 持有bean對(duì)象
- 包含對(duì)bean操作的各種方法: 數(shù)據(jù)庫(kù)讀寫(xiě),網(wǎng)絡(luò)請(qǐng)求
- View :視圖顯示
- 持有P層的引用
- 包含人機(jī)交互的入口方法: onClick, onKeyDown
- Presenter :交互和數(shù)據(jù)之間的控制業(yè)務(wù)
- 持有M和V的引用
- 包含對(duì)應(yīng)Model需要的業(yè)務(wù)方法
優(yōu)點(diǎn):耦合度低,職責(zé)清晰,便于測(cè)試
缺點(diǎn):接口和類(lèi)較多
MVP案例-局域網(wǎng)udp通信
分析:
- V層:持有P層引用,接收用戶(hù)操作,向用戶(hù)顯示數(shù)據(jù)
- M層:持有Bean,完成對(duì)Bean的發(fā)送和接收
- P層:持有V層和M層引用,完成業(yè)務(wù)邏輯
工程結(jié)構(gòu)

MVPDemo結(jié)構(gòu)圖
Demo界面

界面截圖
UML接口圖

UML
MVVM

875437-9e57c017aa88a959.png
- View: 對(duì)應(yīng)于Activity和xml,負(fù)責(zé)View的繪制以及與用戶(hù)交互
- Model: 實(shí)體模型
- ViewModel: 負(fù)責(zé)完成View于Model間的交互,負(fù)責(zé)業(yè)務(wù)邏輯(DataBinding)
Databinding
Google在2015年IO 大會(huì)上推出的 Data Binding 庫(kù),主要用于更加方便的實(shí)現(xiàn)MVVM模型
DataBinding基本使用
- gradle配置:
dataBinding {
enabled = true
}
- xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
</layout>
<data>
<variable
name="user"
type="com.xgimi.mvvmdemo.User"/>
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
- bean
- 繼承BaseObservable
- 對(duì)需要綁定的屬性增加@Bindable注解
- 在需要進(jìn)行數(shù)據(jù)更新的方法中使用notifyPropertyChanged(int)方法進(jìn)行更新
public class User extends BaseObservable{
@Bindable
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
- xml中其他用法:
三目運(yùn)算:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name != null ? user.name : user.defaultName}" />
引入靜態(tài)類(lèi):
public class MyUtil {
public static String checkUserName(String name) {
if (name.length() <= 1) {
return "too short";
} else {
return name;
}
}
}
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{MyUtil.checkUserName(user.name)}"/>
使用View屬性:
<import type="android.view.View"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{user.isAdult ? View.visiable : View.gone}"
android:text="@{user.name != null ? user.name : user.defaultName}" />
雙向綁定:
<import type="com.xgimi.presenter.MyPresenter"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{MyPresenter.onBtnClick}"
/>