您的位置:首页 > 其它

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

/**
* 有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!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mvvm