簡(jiǎn)介
背景
這幾年 MVP 架構(gòu)在安卓界非常流行,幾乎已經(jīng)成為主流框架勉躺,它讓業(yè)務(wù)邏輯 和 UI操作相對(duì)獨(dú)立玖雁,使得代碼結(jié)構(gòu)更清晰缀旁。
MVVM 在前端火得一塌糊涂阻星,而在安卓這邊卻基本沒見到幾個(gè)人在用挪蹭,看到介紹 MVVM 也最多是講 DataBinding 或 介紹思想的讽坏。偶爾看到幾篇提到應(yīng)用的溃列,還是對(duì)谷歌官網(wǎng)的Architecture Components 文章的翻譯。
相信大家看別人博客或官方文檔的時(shí)候懊渡,總會(huì)碰到一些坑刽射。要么入門教程寫得太復(fù)雜(無(wú)力吐槽,前面寫一堆原理距贷,各種高大上的圖柄冲,然并卵吻谋,到實(shí)踐部分一筆帶過(guò)忠蝗,你確定真的是入門教程嗎)。要么就是簡(jiǎn)單得就是一個(gè) hello world漓拾,然后就沒有下文了(看了想罵人)阁最。
實(shí)在看不下去的我,決定插手你的人生骇两。
目錄
《安卓-深入淺出MVVM教程》大致分兩部分:應(yīng)用篇速种、原理篇。
采用循序漸進(jìn)方式低千,內(nèi)容深入淺出配阵,符合人類學(xué)習(xí)規(guī)律,希望大家用最少時(shí)間掌握 MVVM示血。
應(yīng)用篇:
01 Hello MVVM (快速入門)
02 Repository (數(shù)據(jù)倉(cāng)庫(kù))
03 Cache (本地緩存)
04 State Lcee (加載/空/錯(cuò)誤/內(nèi)容視圖)
05 Simple Data Source (簡(jiǎn)單的數(shù)據(jù)源)
06 Load More (加載更多)
07 DataBinding (數(shù)據(jù)與視圖綁定)
08 RxJava2
09 Dragger2
10 Abstract (抽象)
11 Demo (例子)
12-n 待定(歡迎 github 提建議)
原理篇
01 MyLiveData(最簡(jiǎn)單的LiveData)
02-n 待定(并不是解讀源碼棋傍,那樣太無(wú)聊了,打算帶你從0擼一個(gè) Architecture)
關(guān)于提問(wèn)
本人水平和精力有限难审,如果有大佬發(fā)現(xiàn)哪里寫錯(cuò)了或有好的建議瘫拣,歡迎在本教程附帶的 github倉(cāng)庫(kù) 提issue。
What告喊?為什么不在博客留言麸拄?考慮到國(guó)內(nèi)轉(zhuǎn)載基本無(wú)視版權(quán)的情況,一般來(lái)說(shuō)你都不是在源出處看到這篇文章黔姜,所以留言我也一般是看不到的拢切。
教程附帶代碼
https://github.com/ittianyu/MVVM
應(yīng)用篇放在 app 模塊下,原理篇放在 implementation 模塊下秆吵。
每一節(jié)代碼采用不同包名失球,相互獨(dú)立。
前言
上一節(jié)是介紹了 LoadMore,也就是常見的 List 下拉刷新和加載更多实苞。
這一節(jié)是在 04 節(jié)的基礎(chǔ)上開始的豺撑,請(qǐng)大家拷貝一份之前04的項(xiàng)目。(注意黔牵,后面幾節(jié)也是從 04 的項(xiàng)目開始聪轿,所以建議保留一份不動(dòng))
從這一節(jié)開始,講的多半是和其他一些類庫(kù)的整合猾浦,所以如果之前不了解這些類庫(kù)的陆错,是會(huì)暈車的。
但也不是你非得把所有篇章都學(xué)會(huì)金赦,比如我認(rèn)識(shí)的很多人音瓷,寧愿用 ButterKnife 也不用 DataBinding(講道理,DataBinding 強(qiáng)大得多夹抗,不僅不用 findViewById绳慎,還能雙向綁定,不知道為什么很少人用)漠烧。
如果你沒有興趣杏愤,完全可以跳過(guò)本節(jié),不影響后面學(xué)習(xí)已脓。
先修要求
- 會(huì)使用 DataBinding
環(huán)境配置
需要在 app build.gradle
中開啟 dataBinding
android {
...
dataBinding {
enabled true
}
...
}
xml
在最外面套一層 layout珊楼,并加上 data
然后讓 tv_id tv_name 和 data 綁定
注意,id 是 int度液, 所以在綁定時(shí)厕宗,需要轉(zhuǎn)換一下
android:text="@{String.valueOf(user.id)}"
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="user"
type="com.ittianyu.mvvm.g_data_binding.common.bean.User"/>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/et_username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:imeOptions="actionSearch"
android:singleLine="true"
android:text="ittianyu" />
<Button
android:id="@+id/btn_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="search" />
</LinearLayout>
<FrameLayout
android:id="@+id/v_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/v_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.id)}"
android:gravity="center" />
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={user.name}"
android:gravity="center" />
</LinearLayout>
<FrameLayout
android:id="@+id/v_error"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Network error, click to reload" />
</FrameLayout>
<FrameLayout
android:id="@+id/v_empty"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="User not exist" />
</FrameLayout>
<FrameLayout
android:id="@+id/v_loading"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
</LinearLayout>
</layout>
View
initView
得益于 DataBinding,我們已經(jīng)不需要 findViewById堕担,可以通過(guò) bind. 來(lái)訪問(wèn) View已慢。
private GActivityUserBinding bind;
private void initView() {
bind = DataBindingUtil.setContentView(this, R.layout.g_activity_user);
bind.setUser(new User());
}
private void showContent() {
bind.vContent.setVisibility(View.VISIBLE);
bind.vEmpty.setVisibility(View.GONE);
bind.vError.setVisibility(View.GONE);
bind.vLoading.setVisibility(View.GONE);
}
...
updateView
之前更新 View,需要通過(guò)引用手動(dòng)去設(shè)置照宝,但現(xiàn)在只需要給 bind 設(shè)置 data 就行蛇受,自動(dòng)映射到 UI。
谷歌大禮包配合DataBinding 打出成噸輸出厕鹃,美滋滋兢仰。
private void updateView(Lcee<User> lcee) {
switch (lcee.status) {
case Content: {
showContent();
bind.setUser(lcee.data);
break;
}
case Empty: {
showEmpty();
break;
}
case Error: {
showError();
break;
}
case Loading: {
showLoading();
break;
}
}
}
總結(jié)
這一節(jié)主要是加入 DataBinding。熟悉 DataBinding 肯定是非常輕松就學(xué)會(huì)拉剂碴。
下一節(jié)也是從 04 基礎(chǔ)上開始講整合 RxJava