//添加依赖
compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'io.reactivex.rxjava2:rxjava:2.1.7' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'com.github.bumptech.glide:glide:4.3.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1' compile 'com.android.support:recyclerview-v7:26.0.0-alpha1' compile 'com.jcodecraeer:xrecyclerview:1.2.0' compile 'com.facebook.fresco:fresco:0.12.0' // 在 API < 14 上的机器支持 WebP 时,需要添加 compile 'com.facebook.fresco:animated-base-support:0.12.0' // 支持 GIF 动图,需要添加 compile 'com.facebook.fresco:animated-gif:0.12.0' // 支持 WebP (静态图+动图),需要添加 compile 'com.facebook.fresco:animated-webp:0.12.0' compile 'com.facebook.fresco:webpsupport:0.12.0' // 仅支持 WebP 静态图,需要添加 compile 'com.facebook.fresco:webpsupport:0.12.0' testCompile 'junit:junit:4.12' main_activity<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.bwei.heqi20171207.MainActivity"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/xrecy" android:layout_width="match_parent" android:layout_height="match_parent"> </com.jcodecraeer.xrecyclerview.XRecyclerView> </LinearLayout>
//rv_list<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/ximg" android:layout_width="250dp" android:layout_height="250dp" fresco:roundAsCircle="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/name" android:layout_below="@+id/ximg" /> </RelativeLayout> //MainActivityimport android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.util.Log; import android.view.View; import com.bwei.heqi20171207.adaptrer.XAdapter; import com.bwei.heqi20171207.bean.News; import com.bwei.heqi20171207.model.NewsModel; import com.bwei.heqi20171207.presenter.NewsPresenter; import com.bwei.heqi20171207.view.IView; import com.facebook.drawee.backends.pipeline.Fresco; import com.jcodecraeer.xrecyclerview.ProgressStyle; import com.jcodecraeer.xrecyclerview.XRecyclerView; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static android.R.id.list; public class MainActivity extends AppCompatActivity implements IView{ private XRecyclerView xrecy; private NewsPresenter presenter; private XAdapter xAdapter; private List<News> list; private int num = 10; private Map<String, String> map; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.activity_main); xrecy = findViewById(R.id.xrecy); //设置可上拉 xrecy.setPullRefreshEnabled(true); xrecy.setLoadingMoreEnabled(true); //设置上拉下拉样式 xrecy.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader); xrecy.setLaodingMoreProgressStyle(ProgressStyle.BallClipRotate); LinearLayoutManager manager = new LinearLayoutManager(this); xrecy.setLayoutManager(manager); map = new HashMap<>(); map.put("key", "71e58b5b2f930eaf1f937407acde08fe"); map.put("num","10"); presenter = new NewsPresenter(); presenter.attachView(this); presenter.getData(map); xrecy.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { num = 10; list.clear();//清空一下集合 NewsModel newsModel = new NewsModel(presenter); newsModel.getData(map);; xrecy.refreshComplete();//关闭 } @Override public void onLoadMore() { num++; NewsModel newsModel = new NewsModel(presenter); newsModel.getData(map); xrecy.loadMoreComplete(); } }); } @Override public void onSuccess(Object o) { list = (List<News>)o; XAdapter xAdapter = new XAdapter(this, list); xrecy.setAdapter(xAdapter); xAdapter.notifyDataSetChanged(); } @Override public void onFailed(Exception e) { Log.e("2", "onFailed: " + e.getMessage()); } //内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (presenter != null) { presenter.detachView(); } } } m层 接口import java.util.Map; /** * Created by HQ on 2017/12/7. */ public interface IModel { void getData(Map<String,String> map); } NewsModel类import com.bwei.heqi20171207.bean.MessageBean; import com.bwei.heqi20171207.bean.News; import com.bwei.heqi20171207.http.RetrofitUtils; import com.bwei.heqi20171207.presenter.NewsPresenter; import java.util.List; import java.util.Map; import io.reactivex.Flowable; /** * Created by HQ on 2017/12/7. */ //网络请求 public class NewsModel implements IModel { private NewsPresenter presenter; public NewsModel(NewsPresenter presenter){ this.presenter=presenter; } @Override public void getData(Map<String, String> map) { Flowable<MessageBean<List<News>>> flowable = RetrofitUtils.getInstance().getApiService() .getHeqi(map); presenter.getNews(flowable); } }
//v层
接口public interface IView { void onSuccess(Object o); void onFailed(Exception e); } p层 接口import java.util.Map; /** * Created by HQ on 2017/12/7. */ public interface BasePresenter { void getData(Map<String,String> map); }
NewsPresenter类import android.util.Log; import com.bwei.heqi20171207.bean.MessageBean; import com.bwei.heqi20171207.bean.News; import com.bwei.heqi20171207.model.IModel; import com.bwei.heqi20171207.model.NewsModel; import com.bwei.heqi20171207.view.IView; import org.reactivestreams.Subscriber; import java.util.List; import java.util.Map; import javax.security.auth.login.LoginException; import io.reactivex.Flowable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.DisposableSubscriber; /** * Created by WuXirui * Create Time: 2017/12/6 * Description: */ public class NewsPresenter implements BasePresenter { private IView iv; private DisposableSubscriber subscriber; public void attachView(IView iv) { this.iv = iv; } public void detachView() { if (iv != null) { iv = null; } if (subscriber != null) { if (!subscriber.isDisposed()) { subscriber.dispose(); } } } @Override public void getData(Map<String, String> map) { NewsModel model = new NewsModel(this); model.getData(map); } public void getNews(Flowable<MessageBean<List<News>>> flowable) { subscriber = (DisposableSubscriber) flowable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSubscriber<MessageBean<List<News>>>() { @Override public void onNext(MessageBean<List<News>> listMessageBean) { List<News> newslite = listMessageBean.getNewslite(); Log.i("TAG2",newslite.size()+""); iv.onSuccess(newslite); } @Override public void onError(Throwable t) { iv.onFailed(new Exception(t)); } @Override public void onComplete() { } }); } }
bean包import java.util.List; /** * Created by HQ on 2017/12/7. */ public class MessageBean<T> { /** * code : 200 * msg : success * newslist : [{"ctime":"2016-12-04 13:00","title":"格林:理解科尔吸食大麻 不过我从没吸过","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161204/1-161204120131.jpg","url":"http://www.51tyw.com/nba/2421.html"},{"ctime":"2016-12-04 00:00","title":"三分纪录延续!火箭队连续19场比赛命中10+三分球","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161203/1-161203233J3.jpg","url":"http://www.51tyw.com/nba/2417.html"},{"ctime":"2016-12-04 00:00","title":"詹姆斯谈三连败:是时候紧起来了 必须打得男人点","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161203/1-161203234010.jpg","url":"http://www.51tyw.com/nba/2418.html"},{"ctime":"2016-12-03 12:00","title":"骑士输赢都靠三分?那还要詹姆斯做什么?","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161203/1-161203104344.jpg","url":"http://www.51tyw.com/nba/2407.html"},{"ctime":"2016-12-03 00:00","title":"公牛vs骑士直播看点:詹伟兄弟对决","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161202/1-161202221205.jpg","url":"http://www.51tyw.com/nba/2395.html"},{"ctime":"2016-12-02 22:00","title":"火箭和勇士联手创NBA三分纪录","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161202/1-161202214212.jpg","url":"http://www.51tyw.com/nba/2392.html"},{"ctime":"2016-12-02 22:00","title":"巴克利:勇士打得像女式篮球,太软了!","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161202/1-161202215032.jpg","url":"http://www.51tyw.com/nba/2394.html"},{"ctime":"2016-12-02 20:00","title":"詹姆斯完成月最佳球员4连霸的壮举!","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161202/1-1612021PI0.jpg","url":"http://www.51tyw.com/nba/2388.html"},{"ctime":"2016-12-01 00:00","title":"威少再下三双战书!詹皇会不会先认怂?","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161128/1-16112Q13251.jpg","url":"http://www.51tyw.com/nba/2374.html"},{"ctime":"2016-12-01 00:00","title":"骑士这样的防守想夺冠?也许卫冕只是空谈!","description":"NBA新闻","picUrl":"http://www.51tyw.com/uploads/allimg/161130/1-161130222229.jpg","url":"http://www.51tyw.com/nba/2375.html"}] */ private String code; private String msg; private T newslist; public MessageBean(String code, String msg, T newslist) { this.code = code; this.msg = msg; this.newslist = newslist; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getNewslite() { return newslist; } public void setNewslite(T newslite) { this.newslist = newslist; } @Override public String toString() { return "MessageBean{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + ", newslist=" + newslist + '}'; } }ctime "2016-12-04 13:00" title "格林:理解科尔吸食大麻 不过我从没吸过" description "NBA新闻" picUrl "http://www.51tyw.com/uploads/allimg/161204/1-161204120131.jpg" url "http://www.51tyw.com/nba/2421.html"*/ public class News { private String ctime; private String title; private String description; private String picUrl; private String url; public News(String ctime, String title, String description, String picUrl, String url) { this.ctime = ctime; this.title = title; this.description = description; this.picUrl = picUrl; this.url = url; } public String getCtime() { return ctime; } public void setCtime(String ctime) { this.ctime = ctime; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getPicUrl() { return picUrl; } public void setPicUrl(String picUrl) { this.picUrl = picUrl; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } @Override public String toString() { return "News{" + "ctime='" + ctime + '\'' + ", title='" + title + '\'' + ", description='" + description + '\'' + ", picUrl='" + picUrl + '\'' + ", url='" + url + '\'' + '}'; } } http包import com.bwei.heqi20171207.bean.MessageBean; import com.bwei.heqi20171207.bean.News; import java.util.List; import java.util.Map; import io.reactivex.Flowable; import retrofit2.http.GET; import retrofit2.http.QueryMap; /** * Created by HQ on 2017/12/7. */ 接口 public interface ApiService { @GET("nba/") Flowable<MessageBean<List<News>>> getHeqi(@QueryMap Map<String, String> map); }
RetrofitUtils工具类import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /** * Created by WuXirui * Create Time: 2017/12/6 * Description: */ public class RetrofitUtils { private static volatile RetrofitUtils instance; private ApiService apiService; private RetrofitUtils() { Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .baseUrl("http://api.tianapi.com/") .build(); apiService = retrofit.create(ApiService.class); } //单例模式 public static RetrofitUtils getInstance() { if (instance == null) { synchronized (RetrofitUtils.class) { if (null == instance) { instance = new RetrofitUtils(); } } } return instance; } public ApiService getApiService() { return apiService; } }
adapterimport android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.bwei.heqi20171207.R; import com.bwei.heqi20171207.bean.News; import com.facebook.drawee.view.SimpleDraweeView; import java.util.ArrayList; import java.util.List; /** * Created by HQ on 2017/12/2. */ public class XAdapter extends RecyclerView.Adapter<XAdapter.ViewHolder>{ private Context context; private List<News> list; public XAdapter(Context context, List<News> list) { this.context = context; this.list = list; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = View.inflate(context, R.layout.rv_list, null); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.ximg.setImageURI(list.get(position).getPicUrl()); holder.name.setText(list.get(position).getTitle()); } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder{ private final SimpleDraweeView ximg; private final TextView name; public ViewHolder(View itemView) { super(itemView); name = (TextView) itemView.findViewById(R.id.name); ximg = (SimpleDraweeView) itemView.findViewById(R.id.ximg); } } }