不知道前面讲解的两篇关于接口开发的文章是不是已经带领你们进入了后台的世界,如果还没有尽兴不要紧,你们自己慢慢撸,这一篇我们开始撸安卓的代码了,就是这么快,飞一般的感觉.
好了,我们二话不多说,打开android studio,反手就是一个基于DrawerLayout模板的工程,我命名为PositionArticle,
首先啥也不多想把自己要用的库添加进来,
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.6.0'
apt 'com.jakewharton:butterknife-compiler:8.6.0'
compile 'com.wuxiaolong.pullloadmorerecyclerview:library:1.1.2'
compile 'com.wx.ovalimageview:roundimageview:1.1.0'
appmodule的gradle文件加入
apply plugin: 'android-apt'
工程的gradle文件加入
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
OK,可以了 !
接下来建目录,我们随心所欲的建几个目录就可以了
下面我们先不忙着界面的开发,我们把retrofit的service配置一下,如下
public interface PAService {
String BASE_USER = "http://10.137.213.28:8080/ssm_projec/";
@POST("user/login.do")
@FormUrlEncoded
Observable> login(@Field("user_account") String account, @Field("user_password") String password);
@GET("user/info.do")
Observable> info(@Query("user_id") int id);
@POST("article/list.do")
@FormUrlEncoded
Observable>> homeArticles(@Field("start") int start, @Field("limit") int limit);
@POST("article/listbyuserid.do")
@FormUrlEncoded
Observable>> articlesByUserId(@Field("user_id") int user_id, @Field("start") int start, @Field("limit") int limit);
@POST("article/add.do")
@FormUrlEncoded
Observable createArticle(@Field("user_id") int user_id, @Field("article_content") String article_content);
@GET("comment/commentsByArticleId.do")
Observable>> commentByArticleId(@Query("article_id") int article_id);
@POST("comment/add.do")
@FormUrlEncoded
Observable addComment(@Field("user_id") int user_id, @Field("article_id") int article_id, @Field("comment_content") String comment_content);
}
我们再把Retrofit获取service的类写了
public class PARetrofit {
public static PAService getPAService(){
return new Retrofit.Builder()
.baseUrl(PAService.BASE_USER)
// 添加Gson转换器
.addConverterFactory(GsonConverterFactory.create())
// 添加Retrofit到RxJava的转换器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(new OkHttpClient())
.build()
.create(PAService.class);
}
}
嗯这个不要太简单,因为我们设计的接口也不多,也不需要对retrofit进行多余的配置.接下来我们把mvp中model层的东西写了,我们可以分为4个model分别为用户数据的model:UserModelImp,文章的model:ArticleModelImp,评论的model:CommentModelImp,点赞的model:ThumbModelImp,当然你也可以不分开就写在一个model里面,随你啦.
看一下model层的实现
是的你没看错,我少了一个,因为我不想写点赞了,后面再写,嘿嘿嘿.IModel里面是接口文件,要不给你们看一下?
public interface IModel {
interface IUserModel {
Observable> login(String account, String password);
Observable> info(int id);
}
interface IArticleModel {
Observable>> homeArticles(int start, int limit);
Observable>> articleByUserId(int id, int start, int limit);
Observable createArticle(int user_id, String article_content);
}
interface ICommentModel {
Observable>> commentsByArticleId(int id);
Observable commitComment(int user_id, int article_id, String comment_content);
}
}
其实写到这里我们的应用已经写完了,就是处理数据嘛,数据都有了嘛,对吧?我们先实现登陆界面,新建一个activity,写好xml文件,大概是这个样子
我的天啊,界面不要太好看是吧?接着写下mvp的view层,代码如下
interface ILoginActivityView {
String getUserAccount();
String getUserPassword();
void onLoginSuccess();
void onLoginFail(String message);
}
很多人不知道这个view层怎么写,其实很简单,你想一下presenter和view交互的时候会发生什么事情就行了,想明白了就知道怎么写了,还有记住一点view不处理逻辑!OK,看下presenter 的实现
public class LoginPresenterImp extends BasePresenter implements IPresenter.ILoginActivityPresenter {
IModel.IUserModel iUserModel;
public LoginPresenterImp(IView.ILoginActivityView view) {
super(view);
iUserModel = new UserModelImp();
}
@Override
public void login(String account, String password) {
if (TextUtils.isEmpty(view.getUserAccount())) {
view.onLoginFail("没有账号能行?");
return;
}
if (TextUtils.isEmpty(view.getUserPassword())) {
view.onLoginFail("没有密码能行?");
return;
}
iUserModel.login(account, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer>() {
@Override
public void accept(BaseHttpResult userEntityBaseHttpResult) throws Exception {
if (userEntityBaseHttpResult == null) {
view.onLoginFail("error result data");
} else {
if (userEntityBaseHttpResult.isSuccess()) {
UserUtil.getInstance().setUserId(userEntityBaseHttpResult.getData().getUser_id());
UserUtil.getInstance().setUserAccount(userEntityBaseHttpResult.getData().getUser_account());
UserUtil.getInstance().setUserPasswrod(userEntityBaseHttpResult.getData().getUser_password());
UserUtil.getInstance().setUserName(userEntityBaseHttpResult.getData().getUser_name());
view.onLoginSuccess();
} else {
view.onLoginFail(userEntityBaseHttpResult.getMessage());
}
}
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
view.onLoginFail(throwable.getMessage());
}
});
}
}
粗略的看一下就是,rxjava2.0的订阅方法发生了改变,我这里使用的是两个Consumer参数的那个订阅方法,前一个consumer处理返回的结果,后一个是处理异常的.不知道是不是对于异常的处理变的比以前灵活了,这个后面再来研究.
看下LoginActivity 是代码
public class LoginActivity extends BaseActivity implements IView.ILoginActivityView {
IPresenter.ILoginActivityPresenter iLoginActivityPresenter;
@BindView(R.id.et_account)
EditText etAccount;
@BindView(R.id.et_password)
EditText etPassword;
@BindView(R.id.btn_login)
Button btnLogin;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
iLoginActivityPresenter = new LoginPresenterImp(this);
etAccount.setText(UserUtil.getInstance().getUserAccount());
etPassword.setText(UserUtil.getInstance().getUserPassword());
}
@Override
public String getUserAccount() {
return etAccount.getText().toString();
}
@Override
public String getUserPassword() {
return etPassword.getText().toString();
}
@Override
public void onLoginSuccess() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
public void onLoginFail(String msg) {
showToast(msg);
}
@OnClick(R.id.btn_login)
public void onClick() {
iLoginActivityPresenter.login(etAccount.getText().toString(), etPassword.getText().toString());
}
}
我把两个项目都打包了放在csdn 的下载,下面是下载的地址
http://download.csdn.net/download/wlj644920158/9884937