我的App全栈之路(6)安卓端开发

不知道前面讲解的两篇关于接口开发的文章是不是已经带领你们进入了后台的世界,如果还没有尽兴不要紧,你们自己慢慢撸,这一篇我们开始撸安卓的代码了,就是这么快,飞一般的感觉.

好了,我们二话不多说,打开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'

可以看到我们开始尝试一下rxjava2.0结合retrofit撸一次,想想都刺激,其实rxjava2.0跟1.0用法上就稍微有点变化,但是基本面貌没有多大变化,然后是一个butterknife注解框架,再随便找了一个下拉刷新上拉加载的框架(这个框架不是很酷炫不推荐给你们),接着就是一个圆形Imageview 的库,基本就需要这些后面要用到再来添加,不过这个butterknife要稍微配置一下,

appmodule的gradle文件加入

apply plugin: 'android-apt'

工程的gradle文件加入

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
OK,可以了 !

接下来建目录,我们随心所欲的建几个目录就可以了

我的App全栈之路(6)安卓端开发_第1张图片

下面我们先不忙着界面的开发,我们把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层的实现

我的App全栈之路(6)安卓端开发_第2张图片
是的你没看错,我少了一个,因为我不想写点赞了,后面再写,嘿嘿嘿.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文件,大概是这个样子

我的App全栈之路(6)安卓端开发_第3张图片

我的天啊,界面不要太好看是吧?接着写下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());
    }
}

BaseActivity就封装了一下Toast的显示,其他的没什么了.到这里为止我们就只写到登陆就基本可以了,后面的开发流程基本就是记这个节奏,也没有什么难的地方,不需要额外的技术,就是堆代码.OK,看下app的截图吧

我的App全栈之路(6)安卓端开发_第4张图片

我的App全栈之路(6)安卓端开发_第5张图片

我的App全栈之路(6)安卓端开发_第6张图片

我的App全栈之路(6)安卓端开发_第7张图片

我的App全栈之路(6)安卓端开发_第8张图片
我把两个项目都打包了放在csdn 的下载,下面是下载的地址
http://download.csdn.net/download/wlj644920158/9884937

你可能感兴趣的:(android)