关于water的mvp框架的使用

                                         关于water的mvp框架的使用

    注意:此文档供同组的 Android 开发 人员 阅读,其他人阅读可能会比较困难。   

    注意:本文档配合Databinding 配合  lambda表达式进行实现。

    开发工具:Andriod Studio 3.1.3, Gradle 版本 4.4

    由于标准的MVP模式比较麻烦,要创建Contract 类,并且要包含View和Presenter两个接口。结构上比较麻烦,所以,对其进行优化。

    1.添加依赖:     

            (1)  Databinding   使用添加依赖

 //支持dataBinding
 dataBinding {
     enabled = true
 }

(2)  lambda表达式 使用添加依赖

 //支持jdk1.8
 compileOptions {
     targetCompatibility 1.8
     sourceCompatibility 1.8
 }

注意:以上两个依赖都添加到要使用的 模块 

例如:

 android{

      //其他依赖 省略

     //支持dataBinding

    dataBinding {

           enabled = true

    }

//支持jdk1.8

    compileOptions {

        targetCompatibility 1.8

        sourceCompatibility 1.8

    }

}

 

2.创建layout文件 

以下  a_login.xml  布局文件(处理用户登录的页面)

注意:此页面比较复杂,不需要关注其全部内容,只需关注标红处的内容即可。

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="viewModel"
            type="java.lang.String"/>

        <variable
            name="click"
            type="android.view.View.OnClickListener"/>
    </data>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:tools="http://schemas.android.com/tools"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

        <!--<include layout="@layout/title_bar"/>-->
        <RelativeLayout
            android:id="@+id/tool_bar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/white">

            <com.wxkj.login.view.TextImageView
                android:id="@+id/btnLeft"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true"
                android:onClick="@{click}"
                android:paddingLeft="18dp"
                android:paddingRight="18dp"/>

            <android.support.v7.widget.AppCompatTextView
                android:id="@+id/toolbar_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textColor="@color/grey_1"
                android:textSize="16sp"/>

            <com.wxkj.login.view.TextImageView
                android:id="@+id/btnRight"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentRight="true"
                android:layout_gravity="right"
                android:paddingLeft="18dp"
                android:paddingRight="18dp"/>
        </RelativeLayout>

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/view"
            android:layout_alignLeft="@+id/line1"
            android:layout_alignStart="@+id/line1"
            android:background="@null"
            android:text="登录"
            android:textColor="@color/grey_1"
            android:textSize="24sp"/>

        <TextView
            android:id="@+id/login_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@id/tool_bar"
            android:layout_marginRight="20dp"
            android:layout_marginTop="25dp"
            android:onClick="@{click}"
            android:text="验证码登录"
            android:textColor="@color/orange"
            android:textSize="16sp"/>

        <View
            android:id="@+id/view"
            android:layout_width="wrap_content"
            android:layout_height="0.5dp"
            android:layout_alignLeft="@id/login_type"
            android:layout_alignParentRight="true"
            android:layout_alignRight="@id/login_type"
            android:layout_below="@id/login_type"
            android:layout_marginRight="20dp"
            android:layout_marginTop="2dp"
            android:background="@color/orange"/>

        <ImageView
            android:id="@+id/line1"
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_below="@+id/title"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="40dp"
            android:background="@color/grey_3"/>

        <LinearLayout
            android:id="@+id/ll_telphone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/line1"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="15dp"
                android:drawableLeft="@mipmap/tab_icon_login_iphone"
                android:drawablePadding="15dp"
                android:text="+86"
                android:textColor="@color/grey_1"
                android:textSize="18sp"/>

            <LinearLayout
                android:layout_width="0.5dp"
                android:layout_height="match_parent"
                android:layout_marginBottom="10dp"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="10dp"
                android:background="@color/grey_3"/>

            <EditText
                android:id="@+id/et_telphone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:gravity="right|center_vertical"
                android:inputType="phone"
                android:maxLength="11"
                android:hint="请输入手机号"
                android:paddingBottom="20dp"
                android:paddingRight="20dp"
                android:paddingTop="20dp"
                android:text=""/>
        </LinearLayout>

        <ImageView
            android:id="@+id/line2"
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_below="@+id/ll_telphone"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:background="@color/grey_3"/>

        <LinearLayout
            android:id="@+id/et_password_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/line2"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp">

            <EditText
                android:id="@+id/et_password"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_below="@+id/line2"
                android:layout_weight="3"
                android:background="@null"
                android:drawableLeft="@mipmap/tab_icon_login_password"
                android:drawablePadding="10dp"
                android:inputType="textPassword"
                android:paddingBottom="20dp"
                android:hint="请输入密码(6-15位数字与字母组合,如acb123)"
                android:paddingLeft="10dp"
                android:paddingTop="20dp"
                android:text=""/>

            <TextView
                android:id="@+id/bt_get_checknum"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="2"
                android:gravity="right|center"
                android:onClick="@{click}"
                android:text="获取验证码"
                android:textColor="@color/orange"
                android:textSize="15sp"
                android:visibility="gone"/>
        </LinearLayout>

        <ImageView
            android:id="@+id/line3"
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_below="@+id/et_password_layout"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:background="@color/grey_3"/>

        <TextView
            android:id="@+id/tvForgetPwd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/line3"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:onClick="@{click}"
            android:text="忘记密码?"
            tools:ignore="RtlHardcoded"/>

        <!--<TextView-->
        <!--android:id="@+id/tvTermsOfService"-->
        <!--android:layout_width="wrap_content"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:layout_below="@+id/btn_register"-->
        <!--android:layout_centerHorizontal="true"-->
        <!--android:layout_marginTop="20dp"/>-->

        <Button
            android:id="@+id/btn_login"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tvForgetPwd"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="40dp"
            android:background="@drawable/shape_button_orange_1"
            android:onClick="@{click}"
            android:text="登录"
            android:textColor="@color/orange"/>

        <Button
            android:id="@+id/btn_register"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/btn_login"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:background="@drawable/shape_button_grey"
            android:onClick="@{click}"
            android:text="注册"
            android:textColor="@color/grey_1"/>

        <LinearLayout
            android:id="@+id/ll_user_agreement"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/btn_register"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="注册登录即表示同意"
                android:textColor="@color/grey_2"
                android:textSize="@dimen/sp_14"/>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >

                <TextView
                    android:id="@+id/tv_a_home_user_agreement"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="@{click}"
                    android:text="xxx服务条款协议"
                    android:textColor="@color/grey_2"
                    android:textSize="@dimen/sp_14"/>

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_below="@id/tv_a_home_user_agreement"
                    android:layout_marginTop="-2dp"
                    android:background="#000"
                    android:paddingBottom="0dp"/>

            </LinearLayout>


        </LinearLayout>


    </RelativeLayout>
</layout>

3.创建Activity 引入布局文件。

/**
 * 登录页面(主要处理页面展示)
 * 作者:Laughing on 2018/9/4 17:42
 * 邮箱:719240226@qq.com
 */

public class A_Login extends BaseActivity implements LoginView {

        private LoginPresenter mPresenter;

        private ALoginBinding mBinding;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);//软键盘弹出后,让屏幕整体上移
     super.onCreate(savedInstanceState);
     mBinding = DataBindingUtil.setContentView(this, R.layout.a_login);
     initView();
     initData();
     initListener();
 }
private void initData() {
    mPresenter = new LoginPresenter(this, this, this);

}
private void initListener() {
        //mBinding.setClick() 方法 对应a_login.xml中  
       //<variable
          //  name="click"  
         //  type="android.view.View.OnClickListener"/>
        mBinding.setClick(view -> {

//点击事件处理 方法1:在presenter中 进行点击事件处理,这里通常传递一个 view 参数即可,因为要做效验的逻辑处理,                  //所以本方法把电话号码的文本也传递了过去。
            mPresenter.click(view, mBinding.etTelphone.getText().toString().trim());

            //点击事件处理 方法2: 在activity中进行逻辑处理 使得activity中的逻辑比较多
            if (view.getId() == R.id.btn_login) {
                //登录
                if (mBinding.loginType.getText().equals("密码登录")) {
                    //验证码登录
                    login(0);
                } else {
                    //密码登录
                    login(1);
                }

            } else if (view.getId() == R.id.btnLeft) {
                // 左上角 X 号
//                finish();
                Intent intent = null;
                try {
                    intent = new Intent(mContext, Class.forName("com.wxkj.ycw.ui.activity.A_Home"));
                    intent.getBooleanExtra("refreshAPK", false);
                    startActivity(intent);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } else if (view.getId() == R.id.login_type) {
                //登录方式
                loginType();

            } else if (view.getId() == R.id.tvForgetPwd) {
                // 忘记密码? 页面跳转
                Intent intent = new Intent(A_Login.this, RegisterMobileActivity.class);
                intent.putExtra(EXTRA_RETRIEVE_PASSWORD, true);//忘记密码
                startActivity(intent);
//                finish();

            }


            //点击事件处理 方法3:此方法不推荐,只是展示出来给大家了解。
            //单独的点击事件跳转到    用户协议 页面
            mBinding.tvAHomeUserAgreement.setOnClickListener(v1 -> {
                // 跳转到用 户协议页面 在这里可以做任何自己想要的处理
                Intent intent = new Intent(mContext, WebActivity.class);
                intent.putExtra(WebActivity.EXTRA_TITLE, "用户协议");
                intent.putExtra(WebActivity.EXTRA_WEB_URL, BaseApplication.H5_URL + "?type=userAgreement");
                A_Login.this.startActivity(intent);
            });


        });
    }

 

/**

* 获取验证码 成功 

*/

@Override
public void getVerificationCodeSuccess() {
    TimerUtil.countDown(mBinding.btGetChecknum);//开始倒计时
    ToastUtil.showToast(mContext, "验证码已发送");

}

}

 

4.LoginView.java(负责LoginPresenter与A_Activity之间通讯)

 

/**
 * 登录页面
 * 作者:Laughing on 2018/9/4 17:54
 * 邮箱:719240226@qq.com
 */

public interface LoginView {

    /**
     * 获取验证码 成功
     */
    void getVerificationCodeSuccess();

}

 

5.LoginPresenter.java(负责逻辑处理与网络请求)

/**
 * 登录页面
 * 作者:Laughing on 2018/9/4 17:53
 * 邮箱:719240226@qq.com
 */
public class LoginPresenter {
    private LoginView mView;
    private BaseActivity activity;
    private LifecycleProvider lifecycleProvider;
    private final HttpManager mManager;

    public LoginPresenter(LoginView mView, BaseActivity activity, LifecycleProvider lifecycleProvider) {
        this.mView = mView;
        this.activity = activity;
        this.lifecycleProvider = lifecycleProvider;
        mManager = new HttpManager(activity, lifecycleProvider);
    }


    public void click(View view, String phoneNum) {

        if (view.getId() == R.id.btn_register) {
            //注册
            RegisterMobileActivity.startActivity(activity);
//            activity.finish();//去注册时 关闭登录页面

        } else if (view.getId() == R.id.bt_get_checknum) {
            //获取验证码
            if (StrUtil.isMobileNo(phoneNum))
                getVerificationCode(phoneNum);
            else
                ToastUtil.showToast(activity, "请输入正确的手机号");

        }
    }

    /**
     * 发送网络请求   获取验证码
     *
     * @param phoneNum
     */
    private void getVerificationCode(String phoneNum) {
        HashMap<String, String> map = new HashMap<>();
        map.put("telephone", phoneNum);
//        mManager.doHttpDeal(RetrofitHelper.getApiService().getVerificationCode(phoneNum)
        mManager.doHttpDeal(RetrofitHelper.getApiService().getVerificationCode(map)
                , new DefaultObserver<Object>(activity) {
                    @Override
                    public void onSuccess(Object response) {

                        //网络访问成功后需要处理页面刷新 或做跳转,此时回调 LoginView 接口中的方法即可。
                        mView.getVerificationCodeSuccess();
                    }
                });

    }

    /**
     * 去登录
     *
     * @param telephone
     * @param password
     * @param type
     */
    public void sendHttpLogin(final String telephone, final String password, final int type) {
//        LoginReq loginReq = new LoginReq("", "", telephone, password, "1");
        HashMap<String, Object> map = new HashMap<>();
        if (type == 1) {
            //密码 登录
            map.put("telephone", telephone);
            map.put("password", MD5Util.MD5(password));
            map.put("action", "1");
//            mManager.doHttpDeal(RetrofitHelper.getApiService().login2(telephone, MD5Util.MD5(password), "1")
            mManager.doHttpDeal(RetrofitHelper.getApiService().login2(map)
//            mManager.doHttpDeal(RetrofitHelper.getApiService().login2(loginReq)
                    , new DefaultObserver<UserLoginRep>(activity) {
                        @Override
                        public void onSuccess(UserLoginRep response) {
                            loginSuccess(response);
//                            ToastUtil.showToast(activity, "click--->" + response.getTelephone());

                        }
                    });

        } else if (type == 0) {
            //验证码 登录
            map.put("mobile", telephone);
            map.put("code", password);
            map.put("openId", "");
//            mManager.doHttpDeal(RetrofitHelper.getApiService().login(telephone, MD5Util.MD5(password), "0")
            mManager.doHttpDeal(RetrofitHelper.getApiService().login(map)
                    , new DefaultObserver<UserLoginRep>(activity) {
                        @Override
                        public void onSuccess(UserLoginRep response) {
                            loginSuccess(response);

                        }
                    });

        }

    }

    /**
     * 登录成功后保存数据
     *
     * @param response
     */
    private void loginSuccess(UserLoginRep response) {
        Toast.makeText(activity, "登录成功", Toast.LENGTH_SHORT).show();
        AppConfig.flag = true;

        Intent intent = null;
        try {
            intent = new Intent(activity, Class.forName("com.wxkj.ycw.ui.activity.A_Home"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //  intent.putExtra("data", bean);
        activity.startActivity(intent);
        //登录成功保存 token 与用户信息
        saveUserInfo(response);
        activity.finish();


    }

    /**
     * 保存用户信息
     *
     * @param response
     */
    private void saveUserInfo(UserLoginRep response) {
        //缓存数据
        PreferencesManager preferencesManager =     PreferencesManager.getInstance(BaseApplication.getAppContext());
        preferencesManager.put("token", response.getToken());//

        PreferencesManagerForever.getInstance(activity).put("mobile", response.getTelephone());//手机号

        LogUtil.e("TAG", "token---------------------->   " + response.getToken());

    }


}

 

6.BaseActivity.java (负责Activity生命周期控制与其他处理)

/**
 * 基础的activity 实现Retrofit生命周期
 * Created by Water on 2018/3/26.
 */

public class BaseActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
    protected Context mContext = this;
    protected String TAG;
    protected ProgressDialog proDia;
    /**
     * 全局的LayoutInflater对象,已经完成初始化.
     */
    protected LayoutInflater mInflater;

    @Override
    @CallSuper
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //8.1不能使用透明主题
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            this.setTheme(R.style.MyAppTheme);//不透明
        } else {
            this.setTheme(R.style.MyAppThemeTranslucent);//透明主题
        }


        AppManager.getAppManager().addActivity(this);
        lifecycleSubject.onNext(ActivityEvent.CREATE);
        // 不显示标题
        getSupportActionBar().hide();
        // 设置竖屏显示
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        TAG = this.getClass().getSimpleName();
        mInflater = LayoutInflater.from(this);
        proDia = new ProgressDialog(this);
//        proDia.setTitle("正在请求网络");
        proDia.setMessage("努力加载中。。。");
        //状态栏入侵
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
                && isFullStatusBar()) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }




    }

    /**
     * 是否入侵状态栏,默认入侵
     * true 入侵
     * false 不入侵
     */
    protected boolean isFullStatusBar() {
        return true;
    }

    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();

    @Override
    @NonNull
    @CheckResult
    public final Observable<ActivityEvent> lifecycle() {
        return lifecycleSubject.hide();
    }

    @Override
    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
        return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
    }

    @Override
    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> bindToLifecycle() {
        return RxLifecycleAndroid.bindActivity(lifecycleSubject);
    }

    @Override
    @CallSuper
    protected void onStart() {
        super.onStart();
        lifecycleSubject.onNext(ActivityEvent.START);
    }

    @Override
    @CallSuper
    protected void onResume() {
        super.onResume();
        lifecycleSubject.onNext(ActivityEvent.RESUME);



    }

    @Override
    @CallSuper
    protected void onPause() {
        lifecycleSubject.onNext(ActivityEvent.PAUSE);
        super.onPause();
    
    }

    @Override
    @CallSuper
    protected void onStop() {
        lifecycleSubject.onNext(ActivityEvent.STOP);
        super.onStop();
    }

    @Override
    @CallSuper
    protected void onDestroy() {
        lifecycleSubject.onNext(ActivityEvent.DESTROY);
        super.onDestroy();
    }
}

7.总体描述

      本设计主要作用是对页面展示 与 业务逻辑进行分离, activity  负责页面展示与刷新,presenter 负责业务逻辑处理与网络访问获取数据。view类是presenter与activity之间的桥梁,负责回传presenter 的处理结果。

     activity通过调用presenter中的方法进行业务逻辑处理或网络请求,之后再通过 view类把 数据的结果反馈给activity,activity再进行数据展示。

    最后:网络访问通过Retrofit进行。此处不再粘贴代码。

   

   

 
 
 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值