Android 全新最新官方推薦框架MVVM架構搭建
熱文導讀 | 點選標題閱讀
作者:Hacknife (文末附原始碼地址)
地址:http://www.apkbus.com/blog-976112-79418.html
閒話不多少,還是老套路,處理一個登陸的業務。詳細的介紹MVVM我就不多說了,網上一大把,畢竟吹水還是我的弱項。
主要實現的功能有兩個輸入框,一個登陸按鈕,兩個TextView顯示登陸結果。
秀一把我的LoginActivity
@BindLayout(R.layout.activity_login)
public class LoginActivity extends BaseActivity<ILoginViewModel, LoginActivityBriefnessor> implements ILoginView {
@Override
protected ILoginViewModel createViewModel(LoginActivityBriefnessor briefnessor) {
return new LoginViewModel(this, briefnessor);
}
}
是不是超級簡潔,點選事件呢?怎麼不見了,再看一看ViewModel
public class LoginViewModel extends BaseViewModel<ILoginView, ILoginModel, LoginActivityBriefnessor> implements ILoginViewModel {
public LoginViewModel(ILoginView view, LoginActivityBriefnessor briefnessor) {
super(view, briefnessor);
}
@Override
protected ILoginModel createModel() {
return new LoginModel(this);
}
@Override
public void onLoginClick(String account, String pswd) {
if (account.length() < 3) {
Toast.makeText(context(), "賬號不正確", Toast.LENGTH_SHORT).show();
return;
}
if (pswd.length() < 3) {
Toast.makeText(context(), "密碼不正確", Toast.LENGTH_SHORT).show();
return;
}
model.login(account, pswd);
}
@Override
public void callbackLogin(LoginResult result) {
briefnessor.setResult(result);
}
}
ViewModel製作了登陸的資料驗證,以及登陸回撥的實現,model層完成模擬了登陸。
整個登陸的業務流程Activity並沒有參與,在這其中就不得不提一個關鍵的中介軟體Briefness,它連線了View層與Model層,幫我們實現了資料繫結,以及事件傳遞。
我們先看一看佈局是如何實現的
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:imports="com.hacknife.demo.bean.LoginResult,result"a
app:viewModel="com.hacknife.demo.mvvm.viewmodel.ILoginViewModel"
tools:ignore="MissingPrefix">
<EditText
android:id="@+id/et_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="40dp"
android:layout_marginVertical="10dp"
android:hint="賬號" />
<EditText
android:id="@+id/et_pswd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="40dp"
android:layout_marginVertical="10dp"
android:hint="密碼" />
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginHorizontal="40dp"
android:layout_marginVertical="10dp"
android:text="登陸"
app:transfer="onLoginClick($et_account$,$et_pswd$)" />
<LinearLayout style="@style/text_parent" android:layout_marginHorizontal="40dp">
<TextView
style="@style/text_childer"
android:text="返回碼" />
<TextView
android:id="@+id/tv_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:bind="$result.code$" />
</LinearLayout>
<LinearLayout style="@style/text_parent" android:layout_marginHorizontal="40dp">
<TextView
style="@style/text_childer"
android:text="結果:" />
<TextView
android:id="@+id/tv_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:bind="$result.msg$" />
</LinearLayout>
</LinearLayout>
佈局中,根佈局繫結了ViewModel,以及用於展示登陸結果的資料來源。登陸按鈕傳遞單擊登陸事件,剩下的兩個textView繫結相應的欄位。
同時在對應的Activity上繫結相應的佈局檔案,Briefness就能暫時他強大的功能了,它會自動生成[類名+Briefnessor]的類。
public class LoginActivityBriefnessor implements Briefnessor<LoginActivity> {
public EditText et_account;
public EditText et_pswd;
public Button btn_login;
public TextView tv_code;
public TextView tv_msg;
public LoginResult result;
public ILoginViewModel viewModel;
@Override
public void bind(final LoginActivity host, Object source) {
if (!Utils.contentViewExist(host)) {
host.setContentView(R.layout.activity_login);
}
et_account = (EditText) host.findViewById(R.id.et_account);
et_pswd = (EditText) host.findViewById(R.id.et_pswd);
btn_login = (Button) host.findViewById(R.id.btn_login);
tv_code = (TextView) host.findViewById(R.id.tv_code);
tv_msg = (TextView) host.findViewById(R.id.tv_msg);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModel.onLoginClick(et_account.getText().toString().trim() , et_pswd.getText().toString().trim());
}
});
}
@Override
public void clear() {
this.result = null;
this.viewModel = null;
}
@Override
public void clearAll() {
this.result = null;
this.viewModel = null;
this.et_account = null;
this.et_pswd = null;
this.btn_login = null;
this.tv_code = null;
this.tv_msg = null;
}
@Override
public void bindViewModel(Object viewModel) {
this.viewModel = (ILoginViewModel) viewModel;
}
public void setResult(LoginResult result) {
if (result == null) return;
this.result = result;
BriefnessInjector.injector(tv_code,result.getCode());
BriefnessInjector.injector(tv_msg,result.getMsg());
}
}
該類實現了資料繫結,以及向ViewModel傳送訊息附帶輸入框中的值。
Briefness的具體用法,請參考https://github.com/hacknife/briefness
下面說一說BaseActivity
public abstract class BaseActivity<T extends IBaseViewModel,B extends Briefnessor> extends AppCompatActivity implements IBaseView {
protected T viewModel;
protected B briefnessor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
briefnessor = (B )Briefness.bind(this);
viewModel = createViewModel(briefnessor);
briefnessor.bindViewModel(viewModel);
initView();
}
protected abstract T createViewModel(B briefnessor);
@Override
protected void onDestroy() {
super.onDestroy();
if (viewModel != null)
viewModel.dettachView();
}
protected void initView() {
}
@Override
public Context applicationContext() {
return getApplication();
}
@Override
public Activity context() {
return this;
}
}
BaseActivity中初始化了Briefness並建立ViewModel繫結到Briefness,並實現了IBaseView
public interface IBaseView {
Context applicationContext();
Activity context();
}
BaseViewModel繼承AbsViewmodel並實現IBaseViewModel,持有Briefnessor,View,Model。
public abstract class BaseViewModel<V extends IBaseView, M extends IBaseModel, B extends Briefnessor> extends AbsViewModel<V> implements IBaseViewModel {
protected V view;
protected M model;
protected B briefnessor;
public BaseViewModel(V view, B briefnessor) {
this.attachView(view);
this.attachBriefnessor(briefnessor);
this.view = getView();
this.briefnessor = (B) getBriefnessor();
model = createModel();
}
protected abstract M createModel();
@Override
public Context applicationContext() {
return view.applicationContext();
}
@Override
public Activity context() {
return view.context();
}
}
AbsViewModel 的作用主要是釋放相應的連線關係。
public abstract class AbsViewModel<T> implements IBaseViewModel{
protected WeakReference<T> mViewRef;
protected WeakReference<Briefnessor> mBriefnessorRef;
protected void attachView(T view) {
mViewRef = new WeakReference<T>(view);
}
protected void attachBriefnessor(Briefnessor briefnessor) {
mBriefnessorRef = new WeakReference<Briefnessor>(briefnessor);
}
protected T getView() {
return mViewRef.get();
}
protected Briefnessor getBriefnessor() {
return mBriefnessorRef.get();
}
public boolean isViewAttached() {
return mViewRef != null && mViewRef.get() != null & mBriefnessorRef != null & mBriefnessorRef.get() != null;
}
public void dettachView() {
if (mViewRef != null) {
mViewRef.clear();
mViewRef = null;
}
if (mBriefnessorRef != null) {
mBriefnessorRef.clear();
mBriefnessorRef = null;
}
}
}
BaseModel 持有ViewModel,並實現了IBaseView。
public abstract class BaseModel<VM extends IBaseViewModel> implements IBaseModel {
protected VM viewModel;
public BaseModel(VM viewModel) {
this.viewModel = viewModel;
}
@Override
public Context applicationContext() {
return viewModel.applicationContext();
}
@Override
public Activity context() {
return viewModel.context();
}
}
寫的不好,請多多見諒,畢竟小學都沒畢業
如果還有什麼不明白的,程式碼直通車
https://github.com/hacknife/Briefness/tree/master/example/src/main/java/com/hacknife/demo/mvvm
想進阿里嗎?快加入我們的知識星球吧,如下:
如有收穫,歡迎「分享 」
「點贊」「評論 」
媽媽常教導我,讓我養成良好習慣。這樣長大才能成為一個有用的人。良好的習慣是尊敬師長這樣長大才能成為一個有用的人。良好的習慣是尊敬師長,愛護同學,對人有禮貌;是不粗心,做事情不拖拉;還是愛護公物,不浪費糧食。為什麼呢?因為擁有良好習慣,做一個品德高尚的人,懂得尊重別人,才會得到別人的尊重。我要努力地做到這些。我有一些壞習慣,有時候學習很粗心,把一些會做的題做錯。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃飯很慢,有的時候還剩飯。我還起床磨蹭,本來應該迅速地穿好衣服,但是,我總是磨磨蹭蹭地,速度很慢。“我打算在這學期裡,改掉這些壞習慣。早上起來,迅速地穿好衣服,不拖拉。學習不粗心,仔細完成每一道題。吃飯的時候,要很快的把飯吃完,不剩飯。我要從一點一滴做起,逐漸養成良好習慣。我相信自己一定能成為一名品學兼優的好學生!我打算在這學期裡,改掉這些壞習慣。早上起來,迅速地穿好衣服,不拖拉。學習不粗心,仔細完成每一道題。吃飯的時候,要很快的把飯吃完,不剩飯。我要從一點一滴做起,逐漸養成良好習慣。我相信自己一定能成為一名品學兼優的好學生!” 在上幼兒園以前,我什麼也不會幹,就連穿衣服也是媽媽給我穿好,就要上幼兒園了,這樣可不行,媽媽鍛鍊我要學會自己穿衣服。 有一天,媽媽把衣服擺在我面前,開始讓我自己穿。一開始。我又哭又叫就是不穿,還把衣服扔的滿地都是,然後坐在地上開始大哭,等了好長時間,媽媽還是不理我,我只好自己乖乖的把衣服穿好, 一出了房間門,媽媽就笑了起來,再看看我的衣服,毛衣和褲子都穿反了,我趕緊回房間又重新穿了一遍,這次穿好了,拿起外套,可是外套的扣子又扣不上了,釦子可調皮了,好像故意和我作對,我把釦子往釦眼——人類邪惡的根源;愛情——幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話:幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話“親愛的!擦乾你的眼淚,至高無上的愛情已經開啟了我們的眼界,使我們成了它的崇拜者。是它,
媽媽常教導我,讓我養成良好習慣。這樣長大才能成為一個有用的人。良好的習慣是尊敬師長這樣長大才能成為一個有用的人。良好的習慣是尊敬師長,愛護同學,對人有禮貌;是不粗心,做事情不拖拉;還是愛護公物,不浪費糧食。為什麼呢?因為擁有良好習慣,做一個品德高尚的人,懂得尊重別人,才會得到別人的尊重。我要努力地做到這些。我有一些壞習慣,有時候學習很粗心,把一些會做的題做錯。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃飯很慢,有的時候還剩飯。我還起床磨蹭,本來應該迅速地穿好衣服,但是,我總是磨磨蹭蹭地,速度很慢。“我打算在這學期裡,改掉這些壞習慣。早上起來,迅速地穿好衣服,不拖拉。學習不粗心,仔細完成每一道題。吃飯的時候,要很快的把飯吃完,不剩飯。我要從一點一滴做起,逐漸養成良好習慣。我相信自己一定能成為一名品學兼優的好學生!我打算在這學期裡,改掉這些壞習慣。早上起來,迅速地穿好衣服,不拖拉。學習不粗心,仔細完成每一道題。吃飯的時候,要很快的把飯吃完,不剩飯。我要從一點一滴做起,逐漸養成良好習慣。我相信自己一定能成為一名品學兼優的好學生!” 在上幼兒園以前,我什麼也不會幹,就連穿衣服也是媽媽給我穿好,就要上幼兒園了,這樣可不行,媽媽鍛鍊我要學會自己穿衣服。 有一天,媽媽把衣服擺在我面前,開始讓我自己穿。一開始。我又哭又叫就是不穿,還把衣服扔的滿地都是,然後坐在地上開始大哭,等了好長時間,媽媽還是不理我,我只好自己乖乖的把衣服穿好, 一出了房間門,媽媽就笑了起來,再看看我的衣服,毛衣和褲子都穿反了,我趕緊回房間又重新穿了一遍,這次穿好了,拿起外套,可是外套的扣子又扣不上了,釦子可調皮了,好像故意和我作對,我把釦子往釦眼——人類邪惡的根源;愛情——幸福和光明的源泉。我一直在這些思想的舞臺上徘徊。突然我發現兩個身影從我面前經過,坐在不遠的草地上。這是一對從農田那邊走過來的青年男女。農田那邊有農民的茅舍。在一陣令人傷心的沉默之後,隨著一聲長嘆,我聽見從一個肺癆病人的嘴裡說出了這樣的話:“親愛的!擦乾你的眼淚,至高無上的愛情已經開啟了我們的眼界,使我們成了它的崇拜者。是它,
如你有好的文章想和大家分享歡迎投稿,直接向我投遞文章連結即可
最後,國慶福利來了,我們的知識星球已達到1000人了,之前說過到達1000人時將大大幅漲價到169元,為了反饋大家對我們的關注和厚愛,特此維持現價99元最後一天,今天后(今晚 00:00)後將漲到169元,歡迎大家加入我們的知識星球,更多星球資訊參見:
微信掃描或者點選上方二維碼領取Android\Python\AI\Java等高階進階資源
更多學習資料點選下面的“閱讀原文”獲取
相關文章
- Android官方架構元件Navigation:大巧不工的Fragment管理框架Android架構元件NavigationFragment框架
- Android MVVM元件化架構方案AndroidMVVM元件化架構
- Android框架搭建1-架構選型Android框架架構
- iOS應用千萬級架構:MVVM框架iOS架構MVVM框架
- Android 官方架構元件之 LifecycleAndroid架構元件
- Android 官方架構元件(一)——LifecycleAndroid架構元件
- Android 官方架構元件(二)——LiveDataAndroid架構元件LiveData
- Android 官方架構元件(三)——ViewModelAndroid架構元件View
- 推薦系統工程架構架構
- Android專案架構搭建Android架構
- Android 架構設計:MVC、MVP、MVVM和元件化Android架構MVCMVPMVVM元件化
- MVVM框架的搭建(二)——專案搭建MVVM框架
- MVVM框架的搭建(一)——背景MVVM框架
- 魅族推薦平臺架構架構
- Android 架構元件的最新進展 (上篇)Android架構元件
- Twitter推薦引擎架構設計分析架構
- MVVM架構篇之DataBinding(-)MVVM架構
- Android MVVM組成結構AndroidMVVM
- Docker搭建官方私有倉庫registry及相關配置(推薦registry)Docker
- MVC、MVP、MVVM,談談我對Android應用架構的理解MVCMVPMVVMAndroid應用架構
- 推薦一張不錯的架構圖架構
- Android官方架構元件ViewModel:從前世今生到追本溯源Android架構元件View
- 六款值得推薦的Android開源框架簡介Android框架
- MVVM框架的搭建(三)——網路請求MVVM框架
- 推薦系統之業務架構總覽架構
- Netflix推薦系統(Part two)-系統架構架構
- 阿里架構師推薦:這十個開源專案,Android開發不容錯過!阿里架構Android
- Android官方架構元件之LiveData + ViewModel + Room 原始碼分析一Android架構元件LiveDataViewOOM原始碼
- iOS架構由淺入深 | MVVMiOS架構MVVM
- Android T-MVVM深度解耦開發框架AndroidMVVM解耦框架
- 詳細解讀!推薦演算法架構——召回演算法架構
- 一個wpf專案的搭建prism框架mvvm框架MVVM
- 從0搭建一個實用的MVVM框架MVVM框架
- Android官方架構元件Lifecycle:生命週期元件詳解&原理分析Android架構元件
- Android官方架構元件Paging:分頁庫的設計美學Android架構元件
- Android官方架構元件LiveData: 觀察者模式領域二三事Android架構元件LiveData模式
- Android元件化框架搭建Android元件化框架
- 2022年架構師推薦閱讀的10本書架構