实例
就这么一个界面咱通过MVC、MVP、MVVM分别搭建一下。
MVC实例
代码结构
1.在layout创建一个布局文件
1. <!--缩减版--> <LinearLayout ...> <EditText android:id="@+id/et_account" .../> </LinearLayout> <LinearLayout ...> <EditText android:id="@+id/et_password" .../> </LinearLayout> <Button android:id="@+id/btn_login" .../> <Button android:id="@+id/btn_back" .../>
2.实体类(User)
1.public class User { private String name; private String password; public User() {} //set or get ... public User(String name, String password) { this.name = name; this.password = password; } }
3.MVCLoginActivity
//用户点击事件 mvcBinding.mcvLogin.btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { user.setName(mvcBinding.mcvLogin.etAccount.getText().toString()); user.setPassword(mvcBinding.mcvLogin.etPassword.getText().toString()); login(user); } }); //逻辑处理 private void login(User user){ if(!user.getName().isEmpty()&&!user.getPassword().isEmpty()){ if(user.getName().equals("scc001")&&user.getPassword().equals("111111")) { Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show(); } }else { Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show(); } }
MVP实例
代码结构
1.Model层
实体类bean,同MVC中的User类,就不贴代码浪费大家时间了。
Model层所要执行的业务逻辑
/** * 功能:接口,表示Model层所要执行的业务逻辑 */ public interface LoginModel { //User实体类;OnLoginFinishedListener presenter业务逻辑的返回结果 void login(User user, OnLoginFinishedListener listener); }
实现类(实现LoginModel接口)
/** * 功能:实现Model层逻辑 */ public class LoginModelImpl implements LoginModel { //第4步:验证帐号密码 @Override public void login(User user, OnLoginFinishedListener listener) { if(user.getName().isEmpty()||!user.getName().equals("scc001")){ //第5步:Model层里面回调Presenter层listener listener.onUserNameError(); }else if(user.getPassword().isEmpty()||!user.getPassword().equals("111111")){ //第5步:Model层里面回调Presenter层listener listener.onPasswordError(); }else { //第5步:Model层里面回调Presenter层listener listener.onSuccess(); } } }
2.Presenter层
当Model层得到请求的结果,回调Presenter层,让Presenter层调用View层的接口方法。
/** * 功能:当Model层得到请求的结果,回调Presenter层,让Presenter层调用View层的接口方法。 */ public interface OnLoginFinishedListener { void onUserNameError(); void onPasswordError(); void onSuccess(); }
完成登录的验证,以及销毁当前View。
/** * 功能:登录的Presenter的接口,实现类为LoginPresenterImpl, * 完成登录的验证,以及销毁当前View。 */ public interface LoginPresenter { //完成登录的验证 void verifyData(User user); //销毁当前View void onDestroy(); }
Presenter实现类,引入 LoginModel(model)和LoginView(view)的引用
/** * 功能:实现类,引入 LoginModel(model)和LoginView(view)的引用 */ public class LoginPresenterImpl implements OnLoginFinishedListener, LoginPresenter { //View层接口 private LoginView loginView; //Model层接口 private LoginModel loginModel; public LoginPresenterImpl(LoginView loginView) { this.loginView = loginView; this.loginModel = new LoginModelImpl(); } //第6步:通过OnLoginFinishedListener验证结果回传到Presenter层 @Override public void onUserNameError() { if (loginView != null) { //第7步:通过loginView回传到View层 loginView.setUserNameError(); loginView.hideProgress(); } } //第6步:通过OnLoginFinishedListener验证结果回传到Presenter层 @Override public void onPasswordError() { if (loginView != null) { //第7步:通过loginView回传到View层 loginView.setPasswordError(); loginView.hideProgress(); } } //第6步:通过OnLoginFinishedListener验证结果回传到Presenter层 @Override public void onSuccess() { if (loginView != null) { //第7步:通过loginView回传到View层 loginView.success(); loginView.hideProgress(); } } @Override public void verifyData(User user) { if (loginView != null) { loginView.showProgress(); } //第3步:调用model层LoginModel接口的login()方法 loginModel.login(user,this); } @Override public void onDestroy() { loginView = null; } }
3.View层
布局文件同MVC中的View层,就不贴代码浪费大家时间了。
Presenter与View交互是通过接口。
/** * 功能:Presenter与View交互是通过接口。 * 接口中方法的定义是根据Activity用户交互需要展示的控件确定的。 */ public interface LoginView { //login是个耗时操作,加载中(一般用ProgressBar) void showProgress(); //加载完成 void hideProgress(); //login账号失败给出提示 void setUserNameError(); //login密码失败给出提示 void setPasswordError(); //login成功 void success(); }
MVPLoginActivity
/** * 功能:需要实现LoginView接口。 */ public class MVPLoginActivity extends AppCompatActivity implements LoginView { LoginPresenterImpl loginPresenterImpl; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { ... //创建一个Presenter对象 loginPresenterImpl = new LoginPresenterImpl(MVPLoginActivity.this); //第1步:用户点击登录 mvpBinding.mvpLogin.btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { User user = new User(); user.setName(mvpBinding.mvpLogin.etAccount.getText().toString()); user.setPassword(mvpBinding.mvpLogin.etPassword.getText().toString()); //第2步:调用Presenter接口中的验证方法 loginPresenterImpl.verifyData(user); } }); } @Override public void showProgress() { //加载中 } @Override public void hideProgress() { //加载完成 } @Override public void setUserNameError() { //第7步:通过loginView回传到View层 //账号错误 Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show(); } @Override public void setPasswordError() { //第7步:通过loginView回传到View层 //密码错误 Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show(); } @Override public void success() { //第7步:通过loginView回传到View层 Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show(); //登录成功 } @Override protected void onDestroy() { super.onDestroy(); loginPresenterImpl.onDestroy(); } }
MVVM实例
1.Model层
实体类bean,继承BaseObservable
public class User extends BaseObservable{ private String name; private String password; public User() { } //BR 的域则是通过在 get 方法上加 @Bindable 生成的 @Bindable public String getName() { return name; } public void setName(String name) { this.name = name; //刷新UI //BR 的域则是通过在 get 方法上加 @Bindable 生成的 notifyPropertyChanged(BR.name); } @Bindable public String getPassword() { return password; } public void setPassword(String password) { this.password = password; //刷新UI notifyPropertyChanged(BR.password); } public User(String name, String password) { this.name = name; this.password = password; } }
2.ViewModel层
ViewModel类,继承自ViewModel
1.public class LoginViewModel extends ViewModel { public User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public void loginResult() { if(user.getName().isEmpty()||!user.getName().equals("scc001")){ user.setName("scc005"); }else if(user.getPassword().isEmpty()||!user.getPassword().equals("111111")){ user.setName("scc004"); }else { user.setName("scc003"); } user.setPassword("111111"); Log.e("--SCC--","LoginViewModel:"+user.getName()+":"+user.getPassword()); } }
3.View层
先看布局文件,布局文件使用了DataBinding。
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <!--为引入的类从新起一个变量名,方便下面使用--> <variable name="loginViewModel" type="com.scc.architecture.mvvm.viewmodel.LoginViewModel" /> </data> <LinearLayout ...> <LinearLayout ...> <EditText android:id="@+id/et_account" ... android:text="@={loginViewModel.user.name}" /> </LinearLayout> <LinearLayout ...> <EditText android:id="@+id/et_password" ... android:text="@={loginViewModel.user.password}" /> </LinearLayout> <Button android:id="@+id/btn_login" ... android:onClick="login" android:text="@string/str_login" /> <Button android:id="@+id/btn_back" ... android:onClick="back" android:text="@string/str_back" /> </LinearLayout> </layout>
MVVMLoginActivity
public class MVVMLoginActivity extends AppCompatActivity { private LoginViewModel loginVM; ActivityMvvmBinding mvvmBinding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //返回activity_mvvm的实体对象 mvvmBinding = DataBindingUtil.setContentView(this, R.layout.activity_mvvm); mvvmBinding.setLifecycleOwner(this); loginVM = new LoginViewModel(); //创建数据源 User user = new User( "scc001", "111111"); //将数据源交给DataBinding loginVM.setUser(user); //设置et_account:scc001|et_password:111111 mvvmBinding.setLoginViewModel(loginVM); } public void login(View view){ loginVM.loginResult(); } public void back(View view){ finish(); } }
写到这里MVC、MCP、MVVM和实例基本写完了,但是感觉自己理解的不是很好,有大佬能指点就更好了。最后,希望对你有借鉴意义。