Android实战(橘子娱乐)-首页(第六篇 Presenter如何将Model层数据传递给View层)

版权声明:欢迎分享,但请注明出处,谢谢 https://blog.csdn.net/qq_28057577/article/details/78295179
前言:
    前一篇  Android实战(橘子娱乐)-首页(第五篇 Glide加载图片的简单封装)讲解了我们加载显示图片的工具util的具体代码细节,最后提到我们这一节将学习presenter实现将Model层数据传递给View层。

我们先来看我们之前学习MainActivity的部分代码:

 
   
  1. public class MainActivity extends BaseActivity implements MainView,
  2. NavigationView.OnNavigationItemSelectedListener,OnRefreshListener,View.OnClickListener{}
 
    
  1. @Override
  2. public void getFilmInfos(Film film) {
  3. mIRecyclerView.setRefreshing(false);
  4. /* mList.clear();*/
  5. for (int i=0;i<film.getSubjects().size();i++) {
  6. mList.add(film.getSubjects().get(i));
  7. }
  8. mMainAdapter.notifyDataSetChanged();
  9. }
     上面的两段代码片可以看出我们的MainActivity继承了MainView这个接口并实现了 getFilmInfos(Film film)这个接口方法,而我们想要的数据刚好就是来自这里的参数film,当然这个Film类是我们根据接口返回的json生成的bean类,我就不贴出代码了。我们贴出MainView这个接口的代码:

MainView.java
 
   
  1. package com.andy.orange.ui.home.view;
  2. import com.andy.orange.bean.Film;
  3. /**
  4. * Created by Andy Lau on 2017/8/10.
  5. */
  6. public interface MainView {
  7. void getFilmInfos(Film movieInfos);
  8. }
MainView接口看起来好简单,我们来看我们的主角MainPresenterImpl类
 
   
  1. package com.andy.orange.ui.home.presenter.impl;
  2. import android.content.Context;
  3. import android.util.Log;
  4. import com.andy.orange.bean.Film;
  5. import com.andy.orange.ui.home.model.MainModel;
  6. import com.andy.orange.ui.home.model.impl.MainModelImpl;
  7. import com.andy.orange.ui.home.presenter.MainPresenter;
  8. import com.andy.orange.ui.home.view.MainView;
  9. import io.reactivex.Observable;
  10. import io.reactivex.Observer;
  11. import io.reactivex.android.schedulers.AndroidSchedulers;
  12. import io.reactivex.disposables.Disposable;
  13. import io.reactivex.schedulers.Schedulers;
  14. /**
  15. * Created by Andy Lau on 2017/8/10.
  16. */
  17. public class MainPresenterImpl implements MainPresenter {
  18. private MainView mainView;
  19. private MainModel mainModel;
  20. private Context cxt;
  21. private static final String TAG ="Andy";
  22. private Film mFilms;
  23. /*
  24. * 带参构造方法
  25. * */
  26. public MainPresenterImpl(Context cxt,MainView mainView){
  27. this.mainView=mainView;
  28. this.cxt=cxt;
  29. Log.d(TAG,"MainPresenterImpl class->MainPresenterImpl()");
  30. mainModel=new MainModelImpl();
  31. }
  32. /*
  33. * 请求获取热门电影
  34. * */
  35. @Override
  36. public void requestHotFilm(int start,int count) {
  37. Log.d(TAG,"MainPresenterImpl class->requestHotFilm()");
  38. Observable<Film> observable=mainModel.loadHotFilm(start,count);
  39. observable.subscribeOn(Schedulers.io())
  40. .observeOn(AndroidSchedulers.mainThread())
  41. .subscribe(new Observer<Film>() {
  42. @Override
  43. public void onSubscribe(Disposable d) {
  44. }
  45. @Override
  46. public void onNext(Film films) {
  47. mFilms=films;
  48. //mainView.getFilmInfos(mFilms);
  49. Log.d(TAG,"MainPresenterImpl class->onNext()");
  50. }
  51. @Override
  52. public void onError(Throwable e) {
  53. }
  54. @Override
  55. public void onComplete() {
  56. Log.d(TAG,"MainPresenterImpl class->onComplete()");
  57. mainView.getFilmInfos(mFilms);
  58. }
  59. });
  60. }
  61. }
    分析:我们看presenter的代码会发现,在构造方法中我们传入并初始化了一个MainView的实例mianView以及初始化了一个MainModel实例mainModel,这个时候相当于MainPresenter持有了Model和View的对象,然后Presenter可以任意调用他们的方法,当然前提是公开的方法。
 
   
  1. public MainPresenterImpl(Context cxt,MainView mainView){
  2. this.mainView=mainView;
  3. this.cxt=cxt;
  4. Log.d(TAG,"MainPresenterImpl class->MainPresenterImpl()");
  5. mainModel=new MainModelImpl();
  6. }
我们再看下面这段代码:
 
   
  1. Observable<Film> observable=mainModel.loadHotFilm(start,count);
看到presenter调用了mainModel的 loadHotFilm()方法返回了一个 Observable < Film > 值,这里就是结合了RxJava执行了网络请求后返回的数据集合;接着看后面的代码会有一个订阅者和观察者的概念,不懂的可以先去学习一下RxJava,我们通过链式调用设置订阅到 Schedulers . io () 观察者在主线程 AndroidSchedulers . mainThread () 再通过subscribe()方法传递的Observer<Film>对象将数据集合通过
 
    
  1. mainView.getFilmInfos(mFilms);
传递到MainView也就是MainActivity。这里就已经把MainPresenter将Model层获取的数据传递给MainView的过程讲清楚了,但是还有一个问题MainModel又是怎样获取到数据的呢?接下来我们来看看,MainModel的实现代码:
 
   
  1. package com.andy.orange.ui.home.model.impl;
  2. import android.util.Log;
  3. import com.andy.orange.api.ApiService;
  4. import com.andy.orange.bean.Film;
  5. import com.andy.orange.ui.home.model.MainModel;
  6. import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
  7. import io.reactivex.Observable;
  8. import retrofit2.Retrofit;
  9. import retrofit2.converter.gson.GsonConverterFactory;
  10. /**
  11. * Created by Andy Lau on 2017/4/24.
  12. */
  13. public class MainModelImpl implements MainModel {
  14. protected final static String TAG="Andy";
  15. @Override
  16. public Observable<Film> loadHotFilm(int start,int count) {
  17. Retrofit retrofit =
  18. new Retrofit.Builder()
  19. .addConverterFactory(GsonConverterFactory.create())
  20. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  21. .baseUrl(ApiService.MOVIE_BASE_URL_HOT).build();
  22. ApiService apiService = retrofit.create(ApiService.class);
  23. Observable<Film> hotFilm = apiService.getHotFilm(start,count);
  24. Log.d(TAG,"MainModelImpl class->loadHotFilm()");
  25. Log.d(TAG,"MainModelImpl: hotFilm"+hotFilm.toString());
  26. return hotFilm;
  27. }
  28. }
    分析:这里网络请求我们用到了Retrofit2.我们通过设置Gson转换和RxJava2调用适配器以及访问基础URL来构建了一个retrofit实例,并通过他的create方法创建一个ApiService然后再调用 ApiService类的getHotFilm()来获取网络请求的数据,那我们来看看ApiService的具体实现:
 
    
  1. package com.andy.orange.api;
  2. import com.andy.orange.bean.Film;
  3. import io.reactivex.Observable;
  4. import retrofit2.http.GET;
  5. import retrofit2.http.Headers;
  6. import retrofit2.http.Path;
  7. import retrofit2.http.Query;
  8. /**
  9. * Created by Andy Lau on 2017/8/10.
  10. */
  11. public interface ApiService {
  12. public static final String MOVIE_BASE_URL_HOT = "https://api.douban.com/v2/";
  13. public static final String MUSIC_BASE_URL = "http://tingapi.ting.baidu.com/v1/restserver/";
  14. //获取热门电影
  15. @GET("movie/top250")
  16. Observable<Film> getHotFilm(@Query("start") int start, @Query("count") int count);
  17. }
        分析:看上面的代码可以看出是通过retrofit2发起的Get请求,根据MianModelImpl的baseUrl设置可以拼接出访问路径: https://api.douban.com/v2/movie/top250?start=0&count=1 当然参数是我随便加上去的。通过Retrofit+RxJava的组合开起来网络请求很简洁对不对,微笑脸!!!

猜你喜欢

转载自blog.csdn.net/qq_28057577/article/details/78295179