依赖
compile 'io.reactivex:rxjava:1.3.4' compile 'io.reactivex:rxandroid:1.2.1' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0-beta4' compile 'com.squareup.okhttp3:okhttp:3.9.0' //compile project(':xrecyclerview') compile 'com.facebook.fresco:fresco:0.12.0'//fresco compile 'com.jcodecraeer:xrecyclerview:1.3.2'//xrecyclerview
权限
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
工具类
public class RetrofitUtils { //用来修饰被不同线程访问和修改的变量,作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。 private static volatile RetrofitUtils instance; private Retrofit retrofit; //提供有参无参构造 private RetrofitUtils(){ } private RetrofitUtils(String baseUrl){ //新建OkClient对象 OkHttpClient client=new OkHttpClient(); retrofit = new Retrofit.Builder() .client(client) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl(baseUrl) .build(); } //有参 public static RetrofitUtils getInstance(String baseUrl){ //判断 if(instance==null){ synchronized (RetrofitUtils.class){ //再次判断 if(null==instance){ instance=new RetrofitUtils(baseUrl); } } } return instance; } //无参 public static RetrofitUtils getInstance(){ //判断 if(null==instance){ //http://api.tianapi.com/nba/?key=71e58b5b2f930eaf1f937407acde08fe&num=10 return getInstance("http://api.tianapi.com/"); } return instance; } // public Retrofit getRetrofit(){ return retrofit; } }
BlogService接口
public interface BlogService { //http://api.tianapi.com/nba/?key=71e58b5b2f930eaf1f937407acde08fe&num=10 @GET("nba/") Observable<JavaBean> getUrl(@Query("key") String key, @Query("num") int num); }
Bean类
public class JavaBean { private int code; private String msg; private List<NewslistBean> newslist; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List<NewslistBean> getNewslist() { return newslist; } public void setNewslist(List<NewslistBean> newslist) { this.newslist = newslist; } public static class NewslistBean { private String ctime; private String title; private String description; private String picUrl; private String 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; } } }
Presenter类
public class Presenter { private Subscription subscribe; private DataView dataView; //提供v层构造方法,建立关联 public void attachView(DataView dataView){ this.dataView = dataView; } /* * Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。 * Schedulers.io() io() 的内部实现是是用一个无数量上限的线程池, * 可以重用空闲的线程 * ,因此多数情况下 io() 比 newThread() 更有效率 * */ //定义方法 public void getData(String key,int num) { Retrofit retrofit = RetrofitUtils.getInstance().getRetrofit(); BlogService service = retrofit.create(BlogService.class); subscribe = service.getUrl(key, num) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<JavaBean>() { @Override public void call(JavaBean javaBean) { List<JavaBean.NewslistBean> list = javaBean.getNewslist(); dataView.success(list); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { } }); } //提供取消关联 public void detachView(){ //当activity销毁时取消定阅防止内存泄漏 if(subscribe!=null){ //判断当前订阅状态 if(subscribe.isUnsubscribed()){ //取消订阅 subscribe.unsubscribe(); } } //如果view不为空,置为空 if(dataView!=null){ dataView=null; } } }
DataView类
public interface DataView { void success(List<JavaBean.NewslistBean> data); void failed(); }
MainActivity类
public class MainActivity extends AppCompatActivity { private List<JavaBean.NewslistBean> list = new ArrayList<>();//用于存储数据 private int num; private String key="71e58b5b2f930eaf1f937407acde08fe"; private XRecyclerView xre_view; private Presenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到控件 xre_view = findViewById(R.id.xre_view); //为xre_view设置控制器 LinearLayoutManager manager=new LinearLayoutManager(MainActivity.this); xre_view.setLayoutManager(manager); //初始化fresco Fresco.initialize(this); //调用方法 getData(num); xre_view.setPullRefreshEnabled(true); xre_view.setLoadingMoreEnabled(true); //刷新 xre_view.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader); //加载更多 xre_view.setLoadingMoreProgressStyle(ProgressStyle.Pacman); //为xre_view设置监听 /* * 刷新 * */ xre_view.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { new Handler().postDelayed(new Runnable() { @Override public void run() { num=10; getData(num); //刷新后关闭头布局消失 xre_view.refreshComplete(); } },2000); } /* * 加载更多 * */ @Override public void onLoadMore() { new Handler().postDelayed(new Runnable() { @Override public void run() { num+=10; getData(num); xre_view.refreshComplete();//关闭尾布局 } },2000); } }); } private void getData(int num) { //创建p层对象 presenter = new Presenter(); presenter.getData(key,num); //调用v接口的方法要实现v presenter.attachView(new DataView(){ private MyAdapter adapter; @Override public void success(List<JavaBean.NewslistBean> data) { Log.d("--", "success: "+data.size()); list.clear(); list.addAll(data); if (adapter==null){ adapter = new MyAdapter(MainActivity.this,data); xre_view.setAdapter(adapter); }else { adapter.notifyDataSetChanged(); } } @Override public void failed() { } }); } @Override protected void onDestroy() { super.onDestroy(); //判断p是否为空 if(presenter!=null){ presenter.detachView();//解除绑定 } } }
MyAdapter代码
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ Context context; List<JavaBean.NewslistBean> data; private XRecyViewHolder xRecyViewHolder; public MyAdapter(Context context, List<JavaBean.NewslistBean> data) { this.data=data; this.context=context; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view=View.inflate(context,R.layout.xre_item,null); //把自定义布局和布局绑定 xRecyViewHolder = new XRecyViewHolder(view); return xRecyViewHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //把自定义holder和自带的绑定 xRecyViewHolder= (XRecyViewHolder) holder; xRecyViewHolder.re_text.setText(data.get(position).getTitle()); xRecyViewHolder.re_img.setImageURI(data.get(position).getPicUrl()); } @Override public int getItemCount() { return data.size(); } class XRecyViewHolder extends RecyclerView.ViewHolder{ private final TextView re_text; private final SimpleDraweeView re_img; public XRecyViewHolder(View itemView) { super(itemView); //找到控件 re_text = itemView.findViewById(R.id.xre_text); re_img = itemView.findViewById(R.id.xre_fresco); } } }
activity_main.xml布局
<?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" android:orientation="vertical" tools:context="com.example.com.recy_rxjava_fresco_retrofit.MainActivity"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/xre_view"> </com.jcodecraeer.xrecyclerview.XRecyclerView> </LinearLayout>
xre_item.xml布局
<?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" android:orientation="horizontal" xmlns:fresco="http://schemas.android.com/apk/res-auto" tools:context="com.example.com.recy_rxjava_fresco_retrofit.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/xre_text" android:text="aaaa"/> <com.facebook.drawee.view.SimpleDraweeView android:layout_width="100dp" android:layout_height="100dp" fresco:roundAsCircle="true" android:id="@+id/xre_fresco"/> </LinearLayout>