最近对RxJava学习比较感兴趣,陆续看了一些不错的文章,也发现了几个不错的开源项目,为了能够掌握在实际项目中RxJava的具体使用,特此来学习一下接触到的几个开源项目,今天就来介绍一个:RxJoke,这个开源项目使用了RxJava+Retrofit以及MVP模式,所以还是有值得学习的地方。
项目效果图
首先是mvpview,封装了view中的一些共性操作
public interface MvpView {
void showLoading(String msg);
void hideLoading();
void showError(String msg, View.OnClickListener onClickListener);
void showEmpty(String msg, View.OnClickListener onClickListener);
void showEmpty(String msg, View.OnClickListener onClickListener, int imageId);
void showNetError(View.OnClickListener onClickListener);
}
然后是jokeView,有特有的操作
public interface JokeView extends MvpView {
//下拉刷新
void refresh(List<ContentlistEntity> data);
//上拉加载更多
void loadMore(List<ContentlistEntity> data);
}
BaseActivity继承mvpview
public class BaseActivity extends AppCompatActivity implements MvpView {
@Override
public void showLoading(String msg) {
}
@Override
public void hideLoading() {
}
@Override
public void showError(String msg, View.OnClickListener onClickListener) {
}
@Override
public void showEmpty(String msg, View.OnClickListener onClickListener) {
}
@Override
public void showEmpty(String msg, View.OnClickListener onClickListener, int imageId) {
}
@Override
public void showNetError(View.OnClickListener onClickListener) {
}
}
MainActivity
public class MainActivity extends BaseActivity implements JokeView,//作为view层必须要继承自定义的view SwipeRefreshLayout.OnRefreshListener, loadMoreListener {
@Bind(R.id.record_recycleview)
AutoLoadRecylerView recordRecycleview;
@Bind(R.id.common_error_txt)
TextView commonErrorTxt;
@Bind(R.id.retry_btn)
Button retryBtn;
@Bind(R.id.common_error)
RelativeLayout commonError;
@Bind(R.id.joke_refresh_layout)
SwipeRefreshLayout jokeRefreshLayout;
private JokePresenter jokePresenter;
private LinearLayoutManager layoutManager;
private int page = 1;
private List<ContentlistEntity> jokeList;
private JokeAdapter jokeAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
initData();
loadData();
}
private void initView() {
jokeRefreshLayout.setOnRefreshListener(this);
layoutManager = new LinearLayoutManager(this);
recordRecycleview.setLayoutManager(layoutManager);
recordRecycleview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration
.VERTICAL_LIST));
recordRecycleview.setLoadMoreListener(this);
}
private void initData() {
jokeList = new ArrayList<>();
jokeAdapter = new JokeAdapter(jokeList);
recordRecycleview.setAdapter(jokeAdapter);
jokePresenter = new JokePresenter();//view层持有presenter层的对象
jokePresenter.attachView(this);//将view和presenter关联
}
private void loadData() {
jokePresenter.loadList(page);//view层通知presenter层去加载数据
page++;
}
//下拉刷新
@Override
public void onRefresh() {
page = 1;
loadData();
}
//上拉加载
@Override
public void onLoadMore() {
loadData();
}
/** * @param data 回调 以下三个方法是presenter回调的函数 用于更新界面 */
@Override
public void refresh(List<ContentlistEntity> data) {
commonError.setVisibility(View.GONE);
jokeList.clear();
jokeList.addAll(data);
jokeAdapter.notifyDataSetChanged();
jokeRefreshLayout.setRefreshing(false);
}
@Override
public void loadMore(List<ContentlistEntity> data) {
commonError.setVisibility(View.GONE);
jokeList.addAll(data);
jokeAdapter.notifyDataSetChanged();
recordRecycleview.setLoading(false);
}
@Override
public void showError(String msg, View.OnClickListener onClickListener) {
super.showError(msg, onClickListener);
commonError.setVisibility(View.VISIBLE);
recordRecycleview.setLoading(false);
jokeRefreshLayout.setRefreshing(false);
}
@OnClick(R.id.retry_btn)
void setRetryBtnonClick() {
onRefresh();
}
@Override
protected void onDestroy() {
super.onDestroy();
jokePresenter.detachView();
}
}
Modle主要用来获取数据
jokeapi
public interface JokeApi {
@Headers("apikey:83ec99fff780989a5376a1bc595ed5ff")
@GET("showapi_joke/joke_text")
Observable<JokeEntity> getJoke(@Query("page") int page);
@GET("showapi_joke/joke_text")
Call<JokeEntity> callJoke(@Header("apikey") String apikey, @Query("page") int page);
}
rxservice
public class RxService {
private static final String BASETESTURL = "http://apis.baidu.com/showapi_open_bus/";
private static OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor
(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build();
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASETESTURL)
.client(okHttpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
private RxService() {
//construct
}
public static <T> T createApi(Class<T> clazz) {
return retrofit.create(clazz);
}
}
public interface Presenter<V extends MvpView> {
//添加view
void attachView(V mvpView);
//移除view
void detachView();
}
public class BasePresenter<T extends MvpView> implements Presenter<T> {
private T mMvpView;
//关联view层对象
@Override
public void attachView(T mvpView) {
mMvpView = mvpView;
}
@Override
public void detachView() {
mMvpView = null;
}
public boolean isViewAttached() {
return mMvpView != null;
}
//获取view层对象
public T getMvpView() {
return mMvpView;
}
public void checkViewAttached() {
if (!isViewAttached()) throw new MvpViewNotAttachedException();
}
public static class MvpViewNotAttachedException extends RuntimeException {
public MvpViewNotAttachedException() {
super("Please call Presenter.attachView(MvpView) before" +
" requesting data to the Presenter");
}
}
}
public class JokePresenter extends BasePresenter<JokeView> {
//presenter层需要view层和model层的对象
@Override
public void attachView(JokeView mvpView) {
super.attachView(mvpView);
}
@Override
public void detachView() {
super.detachView();
}
public void loadList(final int page) {
RxService.createApi(JokeApi.class)//获取model层引用
.getJoke(page)//调用modle层获取数据
.subscribeOn(Schedulers.io())
.map(new Func1<JokeEntity, List<ContentlistEntity>>() {
@Override
public List<ContentlistEntity> call(JokeEntity jokeEntity) {
return jokeEntity.getShowapi_res_body().getContentlist();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ContentlistEntity>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Logger.e(e.getMessage());
getMvpView().showError(null, null);
}
@Override
public void onNext(List<ContentlistEntity> contentlistEntities) {
if (page == 1) {
getMvpView().refresh(contentlistEntities);//presenter通知view中的方法
} else {
getMvpView().loadMore(contentlistEntities);
}
}
});
}
}
比较重要的就是这些地方了,其他地方请参考代码