最近开始学习MVVM,之前一直用mvp,好处大家都知道,文章会分成多个系列,从最简单的基础版MVVM到比较成熟的MVVM,由浅入深,毕竟我也是刚接触,也是跟着别人的项目学的。
参考的项目有:
1.使用MVVM尝试开发Github客户端及对编程的一些思考https://www.jianshu.com/p/b03710f19123;
2.T-MVVM 努力打造简单实用的开发框架https://github.com/SelfZhangTQ/T-MVVM;
3.云阅:一款基于网易云音乐UI,使用玩安卓、Gank.Io及豆瓣api开发的符合Google Material Design的Android客户端https://github.com/youlookwhat/CloudReader;
4.一个简单的结合 Retrofit 和 RxJava 框架实现 MVVM 架构的例子https://github.com/githubhaohao/MVVMRxJavaRetrofitSample
刚接触MVVM的小伙伴可以先看参考项目的第4个,其他三个无论是在代码架构还是规范都比较好,大家有时间可以研究一下,
项目使用玩Android 开放APIhttps://www.wanandroid.com/blog/show/2
一、项目整体结构
views放的是自定义控件主要是菊花图(加载view);
config放的URL;
其他的大家都认识。
MainActivity调用ViewModel的getList方法,ViewModel的调用Repository的getList方法获取数据,
二、具体功能说明
项目只有一个activity,只获取了公众号的列表,为了展示方便,item只显示了一个字段
个人习惯从网络请求说起,数据到适配
1.model(泛指数据源)
1.1请求接口(熟悉Retrofit人都认识)
public interface APIService {
@GET("wxarticle/chapters/json")
Observable<BaseBean<List<PublicNumberBean>>> getList();
}
1.2HttpUtils主要是对Retrofit进行一些初始化方便repository获取
1.3MainRepository只有一个方法获取公众号列表,传入一个观察者
public void getList(Observer<BaseBean<List<PublicNumberBean>>> observer) {
apiService.getList().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
4.说一下BaseBean(后台返回的数据格式,可能会因为没有数据,数据错误等而不同,但类似code或msg一般都会有,可以先判断它们,然后再进行下一步)
public class BaseBean<T> {
private int errorCode;
private String errorMsg;
private T data;
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
2.ViewModel(相当于mvp中Presenter)
2.1MainViewModel(获取列表,传入观察者)
public class MainViewModel{
MainRepository repository = new MainRepository();
private Observer<BaseBean<List<PublicNumberBean>>> observer;
private MainAdapter adapter;
private CompletedListener completedListener;//完成监听主要是为了在activity中关闭菊花图
public MainViewModel( MainAdapter adapter,CompletedListener completedListener) {
this.adapter = adapter;
this.completedListener = completedListener;
}
public void getList() {
observer = new Observer<BaseBean<List<PublicNumberBean>>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(BaseBean<List<PublicNumberBean>> listBaseBean) {
if (listBaseBean.getErrorCode() ==0){
adapter.setData(listBaseBean.getData());
}
}
@Override
public void onError(Throwable e) {
completedListener.onCompleted();
}
@Override
public void onComplete() {
completedListener.onCompleted();
}
};
repository.getList(observer);
}
2.2适配器
holder部分,之前我们的构造函数都是传入的view对象itemview,现在传入的binding对象,注意super,我们知道DataBInding不需要findViewById,所以声明一个binding对象,方便holder调用
class ViewHolder extends RecyclerView.ViewHolder {
private ItemNumberBinding binding;
public ViewHolder(ItemNumberBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
onCreateViewHolder部分,注意和之前不同,直接看代码和之前传入view不同
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ItemNumberBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_number,parent,false);
return new ViewHolder(binding);
}
onBindViewHolder部分,不用一个社数据了
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
PublicNumberBean bean = mBeanList.get(position);
if (bean !=null){
holder.binding.setBean(bean);
}
}
3.View(Activity和布局文件,只展示MainActivity的主要代码)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
binding.recyclerView.setLayoutManager(layoutManager);
adapter = new MainAdapter(this);
binding.recyclerView.setAdapter(adapter);
viewModel = new MainViewModel(adapter,this);
showWaitDialog();//显示加载动画
viewModel.getList();
4.总结
项目很简单,还有很多问题,比如真在请求时,activity被销毁了怎么办,将在下一篇解决一些问题