1、MVVM的选用
(1)接触Android也有很长时间了,大多数时间都是自己在摸索开发,以前由于开发任务重,一般不太敢用新的东西,怕有解决不了的就麻烦了,一直也都有听说过Android的各种框架,MVP,MVVM比较流行,网上说的各有各的优缺点吧,感觉就是大型APP用MVP更好,中小型用MVVM框架更好,因为不用像MVP那样需要建很多类
(2)我自己分析的MVVM的优势:不用像MVP那样建很多类,这个也是我一直没用mvP的原因。写一个activity需要建好多类,感觉好麻烦啊;MVVM就是将一些页面加载数据方法放在实现层中,我以前自己也想将数据加载分离出来,自己就单独写个activity类,感觉不是很好,MVVM正好帮我解决了这个问题,真是如获至宝啊。
(3)MVVM可以和DataBinding完美结合,页面数据加载方便,这条感觉如果用kotlin开发的话效果减少了好多,自己一直不喜欢在页面中写加载数据的代码,但是确实挺好用的。可以尝试使用
(4)我在我自己设计的框架中,并没有用到DataBing,因为不喜欢在xml中写程序加载数据代码,幸好有kotlin也可以不用findviewbyId,所以我就把本身VM框架的给UI赋值的部分移到activity中了。
2、MVVM的具体用法
(1)MVVM的实现主要是通过接口interface来实现的,activity中实现了一个接口,则在其它class类中就可以通过view的方式回调activity,这个就是activity和VM直接传值的方式。而VM和接口M是直接通过定义的接口来实现的。
(2)首先定义一个接口,这个接口定义activity中实现的方法
public interface IBaseView {
/**
* 开始加载
*
* @param loadType 加载的类型 0:第一次记载 1:下拉刷新 2:上拉加载更多
*/
void loadStart(int loadType); /**
* 加载完成
*/
void loadComplete(); /**
* 加载失败
*
* @param message
*/
void loadFailure(String message);
}
(2)定义一个activity,实现这个接口,也就需要实现这个接口的所有方法
public class MainActivity extends AppCompatActivity implements INewsView, XRecyclerView.LoadingListener {
private Context mContext;
private ActivityMainBinding binding;
private NewsAdapter newsAdapter; //新闻列表的适配器
private NewsVM newsVM;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mContext = this;
initRecyclerView();
newsVM = new NewsVM(this, newsAdapter);
}
/**
* 初始化RecyclerView
*/
private void initRecyclerView() {
binding.newsRv.setRefreshProgressStyle(ProgressStyle.BallClipRotate); //设置下拉刷新的样式
binding.newsRv.setLoadingMoreProgressStyle(ProgressStyle.BallClipRotate); //设置上拉加载更多的样式
binding.newsRv.setArrowImageView(R.mipmap.pull_down_arrow);
binding.newsRv.setLoadingListener(this);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
binding.newsRv.setLayoutManager(layoutManager);
newsAdapter = new NewsAdapter(this);
binding.newsRv.setAdapter(newsAdapter);
}
@Override
public void onRefresh() {
//下拉刷新
newsVM.loadRefreshData();
}
@Override
public void onLoadMore() {
//上拉加载更多
newsVM.loadMoreData();
}
@Override
public void loadStart(int loadType) {
if (loadType == FIRST_LOAD) {
DialogHelper.getInstance().show(mContext, "加载中...");
}
}
@Override
public void loadComplete() {
DialogHelper.getInstance().close();
binding.newsRv.loadMoreComplete(); //结束加载
binding.newsRv.refreshComplete(); //结束刷新
}
@Override
public void loadFailure(String message) {
DialogHelper.getInstance().close();
binding.newsRv.loadMoreComplete(); //结束加载
binding.newsRv.refreshComplete(); //结束刷新
ToastUtils.show(mContext, message);
}
}
(3)定义一个类
public class NewsVM implements BaseLoadListener<SimpleNewsBean> {
private static final String TAG = "NewsVM";
private INewsModel mNewsModel;
private INewsView mNewsView;
private NewsAdapter mAdapter;
private int currPage = 1; //当前页数
private int loadType; //加载数据的类型
public NewsVM(INewsView mNewsView, NewsAdapter mAdapter) {
this.mNewsView = mNewsView;
this.mAdapter = mAdapter;
mNewsModel = new NewsModelImpl();
getNewsData();
}
/**
* 第一次获取新闻数据
*/
private void getNewsData() {
loadType = MainConstant.LoadData.FIRST_LOAD;
mNewsModel.loadNewsData(currPage, this);
}
/**
* 获取下拉刷新的数据
*/
public void loadRefreshData() {
loadType = MainConstant.LoadData.REFRESH;
currPage = 1;
mNewsModel.loadNewsData(currPage, this);
}
/**
* 获取上拉加载更多的数据
*/
public void loadMoreData() {
loadType = MainConstant.LoadData.LOAD_MORE;
currPage++;
mNewsModel.loadNewsData(currPage, this);
}
@Override
public void loadSuccess(List<SimpleNewsBean> list) {
if (currPage > 1) {
//上拉加载的数据
mAdapter.loadMoreData(list);
} else {
//第一次加载或者下拉刷新的数据
mAdapter.refreshData(list);
}
}
@Override
public void loadFailure(String message) {
// 加载失败后的提示
if (currPage > 1) {
//加载失败需要回到加载之前的页数
currPage--;
}
mNewsView.loadFailure(message);
}
@Override
public void loadStart() {
mNewsView.loadStart(loadType);
}
@Override
public void loadComplete() {
mNewsView.loadComplete();
}
}
(4)
public interface BaseLoadListener<T> {
/**
* 加载数据成功
*
* @param list
*/
void loadSuccess(List<T> list);
/**
* 加载失败
*
* @param message
*/
void loadFailure(String message);
/**
* 开始加载
*/
void loadStart();
/**
* 加载结束
*/
void loadComplete();
}