MVVM的简单使用

我们知道在今年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!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值