MVVM的简单使用
2016-09-06 11:27
316 查看
我们知道在今年MVP的设计模式非常的火。MVP 是由 MVC 演变而来,在代码的解耦层次更加的独到!避免了更多的代码耦合度。在MVP 中 将 M(modle)层 与 V(View) 层脱离开来,更好的应证了代码的解耦,更多关于MVC、MVP的设计模式的区别可以查看相关的资料,在这里我们简单的梳理下由MVP 演变至MVVM 的过程,MVP重要的核心思想是按业务进行划分,为了更好的解耦,我们队View 也就是Activity 进行拆分,由此而演变为MVVM。
在学习MVVM 之前我们应该先了解下Google 十分NB的 的一个东西 就是,Data Binding Library它的使用方式,我们在这里不做过多的解释,可以参考Google提供的API ,https://developer.android.com/topic/libraries/data-binding/index.html
我们先看Activity
2、Interface 接口的定义
HandlerCallBack
LoginListener
ResultCallBack
3、DataBinding 中Event 时间的绑定中的内容
4、domain JavaBean
5、Presenter 的内容
6、view (MVP 模式)
7、utils
8、build.gradle 配置 具体的还是的需要参考 DataBinding 的API
9、layout activity_main布局
当中更多的是怎么使用DataBinding
1、数据实体传输至控件
2、控件(如:EditText输入的内容) 传输至实体
两者的转换!在啰嗦一下就是当中的使用还是参考Google的API 写个DataBinding 的Demo,然后反过来修改MVP至MVVM。
OK!!
在学习MVVM 之前我们应该先了解下Google 十分NB的 的一个东西 就是,Data Binding Library它的使用方式,我们在这里不做过多的解释,可以参考Google提供的API ,https://developer.android.com/topic/libraries/data-binding/index.html
我们先看Activity
/** * 有MVP 演变至 MVVM * 也就是对View Activity 进行拆分 * */ public class MainActivity extends AppCompatActivity implements LoginView, ResultCallBack { private ProgressBar progressBar; private Login user; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //DataBinding 数据绑定的形式 ,根据API的实现书写即可 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressBar); user = new Login(); binding.setUser(user); LoginEvent event = new LoginEvent(user); binding.setEvent(event); } public void login(View view) { Presenter presenter = new Presenter(); presenter.login(this,this); } @Override public String getUserName() { return user.userName; } @Override public String getPassword() { return user.password; } @Override public void showProgress() { progressBar.setVisibility(View.VISIBLE); } @Override public void dismissProgress() { progressBar.setVisibility(View.GONE); } @Override public void showToast(String toast) { Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show(); } @Override public void Success(Login login) { Intent intent = new Intent(this,SuccessActivity.class); intent.setAction(this.getPackageName()); Bundle bundle = new Bundle(); bundle.putSerializable("javaBean",login); intent.putExtras(bundle); startActivity(intent); } @Override public void Failed(String error) { } }
2、Interface 接口的定义
HandlerCallBack
/** * Created by wangly on 2016/9/6. * 用于处理Thread+Handler+InterfaceCallBack 的形式 */ public interface HandlerCallBack { void Success(Login login); void Failed(String error); }
LoginListener
/** * Created by wangly on 2016/8/22. */ public interface LoginListener { void login(String username, String password, HandlerCallBack back); }
ResultCallBack
/** * Created by wangly on 2016/8/22. * */ public interface ResultCallBack { /** * 登陆成功 * @param login JavaBean */ void Success(Login login); /** * 登陆失败 * @param error ErrorException */ void Failed(String error); }
3、DataBinding 中Event 时间的绑定中的内容
/** * Created by wangly on 2016/9/5. */ public class LoginEvent { private Login user; public LoginEvent(Login login) { this.user = login; } public TextWatcher userNameWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { user.userName = editable.toString(); } }; public TextWatcher passWordWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { user.password = editable.toString(); } }; }
4、domain JavaBean
/** * Created by wangly on 2016/8/22. */ public class Login implements Serializable{ public String userName; public String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Override public String toString() { return "Login{" + "password='" + password + '\'' + ", userName='" + userName + '\'' + '}'; } }
5、Presenter 的内容
public class Presenter { private LoginUtils loginBiz; private ResultCallBack back; public void login(final LoginView loginView, final ResultCallBack back) { loginBiz = new LoginUtils(); this.back = back; loginView.showProgress(); loginBiz.login(loginView.getUserName(), loginView.getPassword(), new HandlerCallBack() { @Override public void Success(Login login) { loginView.showToast("登录成功"); loginView.dismissProgress(); if (back != null){ back.Success(login); } } @Override public void Failed(final String error) { loginView.showToast(error); loginView.dismissProgress(); if (back != null){ back.Failed(error); } } }); } }
6、view (MVP 模式)
/** * Created by wangly on 2016/8/22. * * 负责 View 与 Presenter 通讯的通道 */ public interface LoginView { public String getUserName(); public String getPassword(); public void showProgress(); public void dismissProgress(); void showToast(String toast); }
7、utils
public class LoginUtils implements LoginListener { public final static int SENT_SUCCESS_MESSAGE = 1001; public final static int SENT_FAILED_MESSAGE = 1002; private HandlerCallBack back; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SENT_SUCCESS_MESSAGE: Login login = (Login) msg.obj; back.Success(login); break; case SENT_FAILED_MESSAGE: String error = (String) msg.obj; back.Failed(error); break; default: break; } } }; @Override public void login(final String username, final String password, final HandlerCallBack back) { this.back = back; if ("".equals(username) || null == username) { back.Failed("请输入用户名"); return; } if ("".equals(password) || null == password) { back.Failed("请输入密码"); return; } new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); if ("张三".equals(username) && "111111".equals(password)) { Login login = new Login(); login.setUserName(username); login.setPassword(password); handler.obtainMessage(SENT_SUCCESS_MESSAGE, login).sendToTarget(); } else { handler.obtainMessage(SENT_FAILED_MESSAGE, "用户名或密码错误").sendToTarget(); } } catch (Exception e) { handler.obtainMessage(SENT_FAILED_MESSAGE, "登录失败!" + e.getMessage()).sendToTarget(); } } }).start(); } }
8、build.gradle 配置 具体的还是的需要参考 DataBinding 的API
dataBinding{ enabled = true }
9、layout activity_main布局
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.wangly.mvpmodle.modle.Login"> </variable> <variable name="event" type="com.wangly.mvpmodle.event.LoginEvent"> </variable> </data> <LinearLayout xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".activity.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:id="@+id/tv_userName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:text="UserName" /> <EditText android:id="@+id/et_user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_toEndOf="@+id/tv_userName" android:addTextChangedListener="@{event.userNameWatcher}" android:ems="10" android:hint="Please input username" android:inputType="textPersonName" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:id="@+id/tv_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:text="PassWorld" /> <EditText android:id="@+id/et_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_toEndOf="@+id/tv_password" android:addTextChangedListener="@{event.passWordWatcher}" android:ems="10" android:hint="Please input passworld" android:inputType="textPersonName" /> </RelativeLayout> <Button android:id="@+id/bt_land" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:onClick="login" android:text="Log in" /> <ProgressBar android:id="@+id/progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="100dp" android:indeterminate="false" android:visibility="gone" /> </LinearLayout> </layout>
当中更多的是怎么使用DataBinding
1、数据实体传输至控件
2、控件(如:EditText输入的内容) 传输至实体
两者的转换!在啰嗦一下就是当中的使用还是参考Google的API 写个DataBinding 的Demo,然后反过来修改MVP至MVVM。
OK!!
相关文章推荐
- WPF MVVM示例讲解
- 浅谈JavaScript前端开发的MVC结构与MVVM结构
- ASP.NET小结之MVC, MVP, MVVM比较以及区别(一)
- MVVM模式中ViewModel和View、Model有什么区别?
- ASP.NET小结之MVC, MVP, MVVM比较以及区别(二)
- JavaScript数据绑定实现一个简单的 MVVM 库
- 浅谈 MVC、MVP 和 MVVM 架构模式
- 翻译-ExtJs5 Mvvm
- 浅谈JavaScript前端开发的MVC结构与MVVM结构
- JavaScript数据绑定实现一个简单的 MVVM 库
- 干货集中营-ReactiveCocoa+RXSwift+MVVM
- 对MVC、MVP、MVVM的理解
- Silverlight中使用MVVM(1)--基础
- 详解Android Data Binding (上)
- Android Data Binding 系列(二) -- Binding与Observer实现原理
- AngularJS中ng-class的用法
- 刘铁猛-深入浅出WPF-系列资源汇总
- Mvvm Light Toolkit for wpf/silverlight系列之Command和Events
- IOC Containers and MVVM
- Android Data Binding 使用