需要使用的依赖和权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
compileSdkVersion rootProject.ext.android.compileSdkVersion defaultConfig { applicationId "com.bwie.test.mymvp_demo" minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName }implementation rootProject.ext.dependencies[ "appcompat-v7"]implementation rootProject.ext.dependencies[ "constraint-layout"]implementation rootProject.ext.dependencies[ "retrofit2"]implementation rootProject.ext.dependencies[ "converter-gson"]implementation rootProject.ext.dependencies[ "rxjava2"]implementation rootProject.ext.dependencies[ "rxjava2:rxandroid"]implementation rootProject.ext.dependencies[ "dagger"]annotationProcessor rootProject.ext.dependencies[ "dagger-compiler"]implementation rootProject.ext.dependencies[ "adapter-rxjava"]implementation 'com.facebook.fresco:fresco:0.12.0' // 支持 GIF 动图,需要添加implementation 'com.facebook.fresco:animated-gif:0.12.0'implementation 'com.android.support:support-v4:27.1.1'
在build.gradle存放
apply from: "config.gradle" buildscript {}
需要在项目下创建一个config.gradle文件,使用时将application的路径名改成自己的
ext { android = [ compileSdkVersion: 27, applicationId : "com.bwie.test.mymvp_demo", minSdkVersion : 15, targetSdkVersion : 27, versionCode : 1, versionName : "1.0" ] dependencies = [ "appcompat-v7" : "com.android.support:appcompat-v7:27.1.1", "constraint-layout": "com.android.support.constraint:constraint-layout:1.1.0", "retrofit2" : "com.squareup.retrofit2:retrofit:2.4.0", "converter-gson" : "com.squareup.retrofit2:converter-gson:2.4.0", "adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava2:2.4.0", "rxjava2" : "io.reactivex.rxjava2:rxjava:2.1.13", "rxjava2:rxandroid": "io.reactivex.rxjava2:rxandroid:2.0.2", "dagger" : "com.google.dagger:dagger:2.8", "dagger-compiler" : "com.google.dagger:dagger-compiler:2.7" ] }
activity_login
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".LoginActivity"> <RelativeLayout android:id="@+id/login_title_relative" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <ImageView android:id="@+id/cha" android:layout_width="20dp" android:layout_height="20dp" android:src="@drawable/cha"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="京东登录"/> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/login_title_relative" android:layout_margin="10dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号"/> <EditText android:id="@+id/mobile" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码"/> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <Button android:id="@+id/btLogin" android:text="登录" android:layout_width="match_parent" android:layout_height="wrap_content"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:orientation="horizontal"> <TextView android:id="@+id/text_regist" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="手机快速注册"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="忘记密码"/> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:orientation="horizontal"> <ImageView android:id="@+id/login_by_wechat" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/umeng_socialize_wechat"/> <ImageView android:id="@+id/login_by_qq" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/umeng_socialize_qq"/> </LinearLayout> </RelativeLayout>
activity_regist
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".RegistActivity"> <RelativeLayout android:id="@+id/login_title_relative" android:padding="10dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/cha_iamge" android:src="@drawable/cha" android:layout_width="20dp" android:layout_height="20dp" /> <TextView android:text="注册" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/login_title_relative" android:layout_margin="10dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="账号"/> <EditText android:id="@+id/mobile" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="密码"/> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <Button android:id="@+id/bt" android:layout_margin="10dp" android:text="注册" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>
LoginActivity
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.bwie.test.bean.UserBean; import com.bwie.test.component.DaggerHttpComponent; import com.bwie.test.module.HttpModule; import com.bwie.test.mymvp_demo.base.BaseActivity; import com.bwie.test.mymvp_demo.contract.LoginContract; import com.bwie.test.mymvp_demo.presenter.LoginPresenter; public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginContract.View, View.OnClickListener{ private RelativeLayout mLoginTitleRelative; private EditText mMobile; private EditText mPassword; private Button mBtLogin; private TextView mTextRegist; private ImageView cha; private ImageView mLoginByWechat; private ImageView mLoginByQq; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //隐藏原有标题 getSupportActionBar().hide(); initView(); } @Override public int getContentLayout() { return R.layout.activity_login; } @Override public void inject() { DaggerHttpComponent.builder() .httpModule(new HttpModule()) .build() .inject(this); } private void initView() { mLoginTitleRelative = (RelativeLayout) findViewById(R.id.login_title_relative); mMobile = (EditText) findViewById(R.id.mobile); mPassword = (EditText) findViewById(R.id.password); mBtLogin = (Button) findViewById(R.id.btLogin); mBtLogin.setOnClickListener(this); mTextRegist = (TextView) findViewById(R.id.text_regist); mTextRegist.setOnClickListener(this); cha=(ImageView)findViewById(R.id.cha); cha.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.cha: finish(); case R.id.text_regist: Intent intent = new Intent(LoginActivity.this, RegistActivity.class); startActivity(intent); break; case R.id.btLogin: //需要调用P层,去完成接口调用 String mobile = mMobile.getText().toString(); String password = mPassword.getText().toString(); mPresenter.login(mobile, password); break; } } @Override public void loginSuccess(UserBean userBean) { Toast.makeText(LoginActivity.this, userBean.getMsg(), Toast.LENGTH_SHORT).show(); } }
RegistActivity
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; import com.bwie.test.bean.RegisterBean; import com.bwie.test.component.DaggerHttpComponent; import com.bwie.test.module.HttpModule; import com.bwie.test.mymvp_demo.base.BaseActivity; import com.bwie.test.mymvp_demo.contract.RegisterContract; import com.bwie.test.mymvp_demo.presenter.RegisterPresenter; public class RegistActivity extends BaseActivity<RegisterPresenter> implements RegisterContract.View, View.OnClickListener{ private Button mBt; private ImageView mChaIamge; private RelativeLayout mLoginTitleRelative; private EditText mMobile; private EditText mPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_regist); //隐藏原有标题 getSupportActionBar().hide(); initView(); } @Override public int getContentLayout() { return R.layout.activity_regist; } @Override public void inject() { DaggerHttpComponent.builder() .httpModule(new HttpModule()) .build() .inject(this); } private void initView() { mChaIamge = (ImageView) findViewById(R.id.cha_iamge); mChaIamge.setOnClickListener(this); mLoginTitleRelative = (RelativeLayout) findViewById(R.id.login_title_relative); mMobile = (EditText) findViewById(R.id.mobile); mPassword = (EditText) findViewById(R.id.password); mBt = (Button) findViewById(R.id.bt); mBt.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.cha_iamge: finish(); break; case R.id.bt: String mobile = mMobile.getText().toString(); String password = mPassword.getText().toString(); mPresenter.register(mobile, password); break; } } @Override public void registerSuccess(RegisterBean registerBean) { String msg = registerBean.getCode(); if (msg.equals("0")){ Intent intent = new Intent(RegistActivity.this, LoginActivity.class); startActivity(intent); Toast.makeText(RegistActivity.this, registerBean.getMsg(), Toast.LENGTH_SHORT).show(); }else { Toast.makeText(RegistActivity.this, registerBean.getMsg(), Toast.LENGTH_SHORT).show(); } } }
base文件夹下BaseActivity
import android.os.Bundle; import android.os.PersistableBundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import com.bwie.test.inter.IBase; import javax.inject.Inject; public abstract class BaseActivity <T extends BaseContract.BasePresenter> extends AppCompatActivity implements IBase,BaseContract.BaseView{ @Inject protected T mPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentLayout()); inject(); //绑定 mPresenter.attchView(this); } @Override protected void onDestroy() { super.onDestroy(); //绑定 mPresenter.detachView(); } @Override public void showLoading() { } @Override public void dismissLoading() { } }
BaseContract
public interface BaseContract { //抽取所有Presenter共性,比如绑定,解绑 interface BasePresenter<T extends BaseView>{ void attchView(T view); void detachView(); } //抽取所有View的共性,比如显示进度条和关闭进度 interface BaseView{ //进度条 void showLoading(); //停止进度条 void dismissLoading(); } }
BasePresenter
public class BasePresenter<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> { protected T mView; @Override public void attchView(T view) { this.mView=view; } @Override public void detachView() { if (mView != null) { mView = null; } } }
inter文件夹下IBase
public interface IBase { int getContentLayout(); void inject(); }
contract文件夹下LoginContract
import com.bwie.test.bean.UserBean; import com.bwie.test.mymvp_demo.base.BaseContract; public interface LoginContract { interface View extends BaseContract.BaseView{ void loginSuccess(UserBean userBean); } interface Presenter extends BaseContract.BasePresenter<View>{ void login(String mobile,String password); } }
RegisterContract
import com.bwie.test.bean.RegisterBean; import com.bwie.test.mymvp_demo.base.BaseContract; public interface RegisterContract { interface View extends BaseContract.BaseView{ void registerSuccess(RegisterBean registerBean); } interface Presenter extends BaseContract.BasePresenter<View>{ void register(String mobile,String password); } }
presenter文件夹下LoginPresenter
import com.bwie.test.bean.UserBean; import com.bwie.test.mymvp_demo.base.BasePresenter; import com.bwie.test.mymvp_demo.contract.LoginContract; import com.bwie.test.utils.LoginApi; import javax.inject.Inject; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; public class LoginPresenter extends BasePresenter<LoginContract.View> implements LoginContract.Presenter{ private LoginApi loginApi; @Inject public LoginPresenter(LoginApi loginApi){ this.loginApi = loginApi; } @Override public void login(String mobile, String password) { loginApi.login(mobile, password) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new Observer<UserBean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(UserBean userBean) { mView.loginSuccess(userBean); } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } }
RegisterPresenter
import com.bwie.test.bean.RegisterBean; import com.bwie.test.mymvp_demo.base.BasePresenter; import com.bwie.test.mymvp_demo.contract.RegisterContract; import com.bwie.test.utils.RegisterApi; import javax.inject.Inject; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; public class RegisterPresenter extends BasePresenter<RegisterContract.View> implements RegisterContract.Presenter{ RegisterApi registerApi; @Inject public RegisterPresenter(RegisterApi registerApi) { this.registerApi = registerApi; } @Override public void register(String mobile, String password) { registerApi.register(mobile, password) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new Observer<RegisterBean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(RegisterBean registerBean) { mView.registerSuccess(registerBean); } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } }
component文件夹下HttpComponent
import com.bwie.test.module.HttpModule; import com.bwie.test.mymvp_demo.LoginActivity; import com.bwie.test.mymvp_demo.RegistActivity; import dagger.Component; @Component(modules = HttpModule.class) public interface HttpComponent { void inject(LoginActivity loginActivity); void inject(RegistActivity registActivity); }
module文件夹下HttpModule
import com.bwie.test.utils.Api; import com.bwie.test.utils.LoginApi; import com.bwie.test.utils.LoginApiService; import com.bwie.test.utils.RegisterApi; import com.bwie.test.utils.RegisterApiService; import java.util.concurrent.TimeUnit; import dagger.Module; import dagger.Provides; import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; @Module public class HttpModule { @Provides LoginApi provideLoginApi() { OkHttpClient okHttpClient = new OkHttpClient.Builder() .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(Api.BASEURL) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build(); LoginApiService loginApiService = retrofit.create(LoginApiService.class); return LoginApi.getLoginApi(loginApiService); } @Provides OkHttpClient.Builder provideOkHttpClientBuilder(){ return new OkHttpClient.Builder() .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS); } @Provides RegisterApi provideRegisterApi(OkHttpClient.Builder builder){ RegisterApiService registerApiService = new Retrofit.Builder() .baseUrl("https://www.zhaoapi.cn/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(builder.build()) .build() .create(RegisterApiService.class); return RegisterApi.getRegisterApi(registerApiService); } }
utils文件夹下Api
public interface Api { String BASEURL = "https://www.zhaoapi.cn/"; }
LoginApi
import com.bwie.test.bean.UserBean; import io.reactivex.Observable; public class LoginApi { private static LoginApi loginApi; private LoginApiService loginApiService; private LoginApi(LoginApiService loginApiService) { this.loginApiService = loginApiService; } public static LoginApi getLoginApi(LoginApiService loginApiService) { if (loginApi == null) { loginApi = new LoginApi(loginApiService); } return loginApi; } public Observable<UserBean> login(String mobile, String password) { return loginApiService.login(mobile, password); } }
LoginApiService
import com.bwie.test.bean.UserBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface LoginApiService { @FormUrlEncoded @POST("user/login") Observable<UserBean> login(@Field("mobile") String mobile, @Field("password") String password); }
RegisterApi
import com.bwie.test.bean.RegisterBean; import io.reactivex.Observable; public class RegisterApi { private static RegisterApi registerApi; private RegisterApiService registerApiService; public RegisterApi(RegisterApiService registerApiService) { this.registerApiService = registerApiService; } public static RegisterApi getRegisterApi(RegisterApiService registerApiService){ if (registerApi==null){ registerApi=new RegisterApi(registerApiService); } return registerApi; } public Observable<RegisterBean> register(String mobile, String password){ return registerApiService.register(mobile,password); } }
RegisterApiService
import com.bwie.test.bean.RegisterBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface RegisterApiService { @FormUrlEncoded @POST("user/reg") Observable<RegisterBean> register(@Field("mobile") String mobile, @Field("password") String password); }
bean文件夹下UserBean
public class UserBean { private String msg; private String code; private DataBean data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public DataBean getData() { return data; } public void setData(DataBean data) { this.data = data; } public static class DataBean { private Object age; private String appkey; private String appsecret; private String createtime; private Object email; private Object fans; private Object follow; private Object gender; private Object icon; private Object latitude; private Object longitude; private String mobile; private Object money; private Object nickname; private String password; private Object praiseNum; private String token; private int uid; private Object userId; private String username; public Object getAge() { return age; } public void setAge(Object age) { this.age = age; } public String getAppkey() { return appkey; } public void setAppkey(String appkey) { this.appkey = appkey; } public String getAppsecret() { return appsecret; } public void setAppsecret(String appsecret) { this.appsecret = appsecret; } public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public Object getEmail() { return email; } public void setEmail(Object email) { this.email = email; } public Object getFans() { return fans; } public void setFans(Object fans) { this.fans = fans; } public Object getFollow() { return follow; } public void setFollow(Object follow) { this.follow = follow; } public Object getGender() { return gender; } public void setGender(Object gender) { this.gender = gender; } public Object getIcon() { return icon; } public void setIcon(Object icon) { this.icon = icon; } public Object getLatitude() { return latitude; } public void setLatitude(Object latitude) { this.latitude = latitude; } public Object getLongitude() { return longitude; } public void setLongitude(Object longitude) { this.longitude = longitude; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Object getMoney() { return money; } public void setMoney(Object money) { this.money = money; } public Object getNickname() { return nickname; } public void setNickname(Object nickname) { this.nickname = nickname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Object getPraiseNum() { return praiseNum; } public void setPraiseNum(Object praiseNum) { this.praiseNum = praiseNum; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public Object getUserId() { return userId; } public void setUserId(Object userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } }
RegisterBean
public class RegisterBean { private String msg; private String code; private String data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getData() { return data; } public void setData(String data) { this.data = data; } }