Android MVVM Demo

我寫了一個(gè)簡(jiǎn)單的登錄demo,用的是傳統(tǒng)的Data Binding來(lái)實(shí)現(xiàn)Android的MVVM架構(gòu)。對(duì)于MVVM我覺(jué)得是對(duì)MVP架構(gòu)中P層的一次升華,進(jìn)一步的解耦文留,同時(shí)view與model又是雙向綁定,這種綁定又是支持生命周期檢測(cè)故觅,不用擔(dān)心頁(yè)面銷毀了還有回調(diào)出現(xiàn)厂庇,不需要findViewById也不需要butterknife,不需要拿到具體的View去設(shè)置數(shù)據(jù)綁定監(jiān)聽(tīng)器等等输吏,全由data binding幫我們完成权旷。

build.gradle(app)

dataBinding{
        enabled=true
 }

布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    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">
    <data>
        <variable
            name="viewModel"
            type="com.leostadyn.stackfarm.mvvmtest.UserViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewModel.user.status}"
            android:id="@+id/txt_user_login_status"/>
        <EditText
            android:id="@+id/edit_username"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewModel.user.userName}"
            android:hint="username"/>
        <EditText
            android:id="@+id/edit_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewModel.user.password}"
            android:hint="password"/>
        <Button
            android:id="@+id/btn_submit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:onClick="click"
            android:text="submit"/>

        <ProgressBar
            android:id="@+id/progressBar"
            android:visibility="gone"
            style="?android:attr/progressBarStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


    </LinearLayout>
</layout>

Model

User.java

import android.databinding.ObservableField;
//User模型
public class User {
    //用戶名
    public ObservableField<String >userName=new ObservableField<>();
    //密碼
    public ObservableField<String >password=new ObservableField<>();
    //反饋
    public ObservableField<String >status=new ObservableField<>();

    public User() {
    }
}

ViewModel

UserViewModel.java

import android.content.Context;
import android.util.Log;
import com.leostadyn.stackfarm.mvvmtest.databinding.ActivityMainBinding;
public class UserViewModel {
    private Context context;
    private ActivityMainBinding activityMainBinding;
    public static final String TAG="KKKKKKK";
    public User user;
    public UserLocalData data;
    public UserViewModel(Context context, ActivityMainBinding activityMainBinding){
        this.context=context;
        this.activityMainBinding=activityMainBinding;
    }
    public void init(){
        this.user=new User();
        this.activityMainBinding.setViewModel(UserViewModel.this);
        data=new UserLocalData();
    }
    //登錄
    public void login(){
        //業(yè)務(wù)邏輯
        Log.e(TAG,"status:"+user.status.get());
        Log.e(TAG,"username:"+user.userName.get());
        Log.e(TAG,"password:"+user.password.get());
        //權(quán)限的校驗(yàn)
        if (data.findByUser(this.user))
            this.user.status.set("success");
        else
            this.user.status.set("error");
    }
}

View

MainActivity.java

public class MainActivity extends AppCompatActivity {
    UserViewModel userViewModel;
    ProgressBar progressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        ActivityMainBinding dataBindingUtil=DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
        userViewModel=new UserViewModel(MainActivity.this,dataBindingUtil);
        progressBar=findViewById(R.id.progressBar);
    }
    @Override
    protected void onStart() {
        super.onStart();
        userViewModel.init();
    }
    public void click(View view) {
        progressBar.setVisibility(View.VISIBLE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                userViewModel.login();
                progressBar.setVisibility(View.GONE);
            }
        },2000);
    }
}

模擬數(shù)據(jù)處理

public class UserLocalData {
    //模擬數(shù)據(jù)庫(kù)
    String [] userArray={"user1:password1","user2:password2"};
    public UserLocalData() {
    }
    //查找用戶
    public boolean findByUser(User user){
        if(user==null)
            throw  new NullPointerException("this user object is null");
        for (int i = 0; i <userArray.length; i++) {
            String  userStr=userArray[i];
            String [] userArray=userStr.split(":");
            String username=userArray[0];
            String password=userArray[1];
            if((user.userName.get()).equals(username)&& (user.password.get()).equals(password)){
                return true;
            }
        }
        return false;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拄氯,更是在濱河造成了極大的恐慌躲查,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件译柏,死亡現(xiàn)場(chǎng)離奇詭異镣煮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鄙麦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門典唇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人胯府,你說(shuō)我怎么就攤上這事介衔。” “怎么了骂因?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵炎咖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我寒波,道長(zhǎng)乘盼,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任俄烁,我火速辦了婚禮绸栅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘页屠。我一直安慰自己阴幌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布卷中。 她就那樣靜靜地躺著,像睡著了一般渊抽。 火紅的嫁衣襯著肌膚如雪蟆豫。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天懒闷,我揣著相機(jī)與錄音十减,去河邊找鬼。 笑死愤估,一個(gè)胖子當(dāng)著我的面吹牛帮辟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玩焰,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了洽糟?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤并炮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后甥郑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體逃魄,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年澜搅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伍俘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勉躺,死狀恐怖癌瘾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赂蕴,我是刑警寧澤柳弄,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站概说,受9級(jí)特大地震影響碧注,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜糖赔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一萍丐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧放典,春花似錦逝变、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弥臼,卻和暖如春宴咧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背径缅。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工掺栅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纳猪。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓氧卧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親氏堤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沙绝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355