任务:从网络上获取数据,然后显示在MainActivity的ListView上
一、载入需要用的框架
1、Mvp框架
compile 'com.hannesdorfmann.mosby:mvp:2.0.1'
compile 'com.hannesdorfmann.mosby:viewstate:2.0.1'
2、Retrofit和RxJava框架
compile 'io.reactivex:rxandroid:1.2.0'
compile 'io.reactivex:rxjava:1.1.5'
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
二、设计草图
根据Mvp设计模式:
将提供数据的网络请求,放入model包中。
将显示屏幕数据的类,放入View包中
将处理数据和转换的逻辑,放入Presents包中。
我们这里:只需要实现当获取到数据时候,ListView的显示情况就可以了。
三、开工
1、创建Retrofit的网络请求 Retrofit的使用 放到Model这个包下面
public class ArticleEntity{ //将json数据转换为实体类 private String title; private String detail; public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
public interface DataApi { //发送数据请求 @GET("refreshlayout/api/newdata{pageNumber}.json") Observable<List<ArticleEntity>> getArticles(@Path("pageNumber") int pageNumber); }
最后:创建
public class HttpConnection { //地址:从网上找的 private static final String BASE_URL = "http://7xk9dj.com1.z0.glb.clouddn.com/"; private static HttpConnection mHttConnection; private Retrofit mRetrofit; //创建Retrofit private HttpConnection(){ mRetrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build(); } //使用单例模式,加上双层锁 public static synchronized HttpConnection newInstace(){ if (mHttConnection == null){ synchronized (HttpConnection.class){ mHttConnection = new HttpConnection(); } } return mHttConnection; } //获取数据的方法,将subscriber作为回调接口 public void getData(int pageNum,Subscriber subscriber){ DataApi api = mRetrofit.create(DataApi.class); Observable observable = api.getArticles(pageNum); observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber); } }
2、创建View
分析:根据我们的需求,我们只需要屏幕显示数据这一个动作就可以了,所以我们设计的View是这样的
//实现:创建接口并继承接口MvpView public interface IArticleView extends MvpView{ //获取到数据,显示 void show(ArrayList<ArticleEntity> articleItem); }
3、设计Present类
同样,我们也只需要显示方法就可以了
public class ArticlePresent extends MvpBasePresenter<IArticleView> { private int mViewPage = 0; private HttpConnection mConnection; @Override public void attachView(IArticleView view) { super.attachView(view); mConnection = HttpConnection.newInstace(); } //获取数据,并处理,然后传递给View的中转站 public void show(){ //获取上步骤的View final IArticleView view = getView(); if (view != null){ Subscriber subscriber = new Subscriber() { @Override public void onCompleted() { Log.d("MainActivity","完成了"); } @Override public void onError(Throwable e) { } @Override public void onNext(Object o) { //当获取到了数据,就调用View的方法 view.show((ArrayList<ArticleEntity>)o); } }; //获取相关数据 mConnection.getData(mViewPage,subscriber); } } }
4、MainActivity显示数据
BaseMvpActivity 继承MvpBaseActivity 设计了一个基础封装方法,封装了一些基础方法,
泛型:是在类名后创建的 泛型是在方法的返回值前创建的
public abstract class BaseMvpActivity <V extends MvpView,T extends MvpPresenter<V>>extends MvpActivity<V,T> { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(savedInstanceState); setListener(); } public abstract void initView(Bundle savedInstanceState); public abstract void setListener(); public <VT extends View> VT getViewById(int id){ return (VT) findViewById(id); } }
public class MainActivity extends BaseMvpActivity<IArticleView,ArticlePresent> implements IArticleView{ private ListView mListView; private ArticleAdapter mArticleAdapter; @NonNull @Override public ArticlePresent createPresenter() { return new ArticlePresent(); } @Override public void initView(Bundle savedInstanceState) { mListView = getViewById(R.id.main_listView); mArticleAdapter = new ArticleAdapter(this,new ArrayList<ArticleEntity>()); mListView.setAdapter(mArticleAdapter); } @Override public void setListener() { } @Override public void show(ArrayList<ArticleEntity> articleItem) { mArticleAdapter.addArticles(articleItem); } }
步骤:继承BaseMvpActivity,继承刚才的IAcrticle接口
设计方式:将获取数据的类装入model中,然后指定View显示的接口方法(比如说:没数据时候显示什么界面,有数据的时候显示什么界面,里面的数据是不是不一样了)
在Present完成处理数据和根据不同数据调用View方法的逻辑。