这些天经常用MVP框架来写工程,今天就给大家用MVP框架,RxJava+Retrofit请求网络数据,并recycleView加载,fresco图片加载。
首先加载所需要的权限:
MVP框架,最主要的还是三个层,model层、view层、presenter层,// recycleView compile 'com.android.support:mediarouter-v7:25.0.0' compile 'com.android.support:appcompat-v7:25.0.0' compile 'com.android.support:recyclerview-v7:25.0.0' // reftorfit compile 'com.android.support:design:23.4.0' compile 'com.squareup.retrofit2:retrofit:2.0.1' compile 'com.squareup.retrofit2:converter-gson:2.0.1' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1' compile 'io.reactivex:rxandroid:1.1.0' compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' // fresco compile 'com.facebook.fresco:fresco:0.11.0'
在View层里定义一个接口:Iview:里边就写一个方法,用来传递数据集合,主要在主函数中实现这个借口,重写里边的方法,用来给适配器中添加数据。
package view;
import java.util.List;
import bean.User;
/**
* Created by 笔片 on 2017/11/7.
*/
public interface Iview {
void GetUser(List<User.SongListBean> list);
}
同样,在model中定义一个接口Imodel:
package model;
import java.util.List;
import bean.User;
/**
* Created by 笔片 on 2017/11/7.
*/
public interface Imodel {
void GetJson(String url);
}
在请求网络数据之前,要先用RxJava来拼接接口的URL,新建一个Api.class,将请求的接口地址写到这个类里边,也比较省事,规范一点
Api.class:
package api;
/**
* Created by 笔片 on 2017/11/7.
*/
public class Api {
public static final String URL_HOME = "http://tingapi.ting.baidu.com/v1/restserver/";
}
,新建一个接口
ApiService :
package inter;
import bean.User;
import retrofit2.http.GET;
import rx.Observable;
/**
* Created by 笔片 on 2017/11/7.
*/
public interface ApiService {
@GET("ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0")
Observable<User> getNoParams();
}
,在
定义一个类
ApiServices,来实现这个接口
package inter;
import bean.User;
import rx.Observable;
/**
* Created by 笔片 on 2017/11/7.
*/
public class ApiServices implements ApiService {
@Override
public Observable<User> getNoParams() {
return null;
}
}
新建一个usermodel.class,并在这个类中实现Imodel方法。这个方法中主要用来请求网络数据,添加Retrofit的拦截器,这其中的 LoggingInterceptor 就是这个接口的拦截器,这个需要自己改一下,
package model;
import java.util.List;
import api.Api;
import bean.User;
import inter.ApiService;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* 在usermodel 中请求网络数据,做耗时操作
* Created by 笔片 on 2017/11/7.
*/
public class usermodel implements Imodel{
public OnFinishLisenter lisenter;
public void setLisenter(OnFinishLisenter lisenter) {
this.lisenter = lisenter;
}
/**
* 利用Retrofit请求网络数据,
* 加载拦截器:得到一个OKHttpClick对象,利用建造者模式加载拦截器,并且在创建retrofit时,添加上OkHttpClick对象
* @param list
*/
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
@Override
public void GetJson(String url) {
// 添加一个拦截器
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build();
// 创建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
// 添加拦截器到Retrofit中
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
// 通过动态代理得到网络接口对象
ApiService apiservice = retrofit.create(ApiService.class);
Observable<User> user = apiservice.getNoParams();
user.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(User user) {
List<User.SongListBean> song_list = user.getSong_list();
lisenter.OnFinish(song_list);
}
});
}
}
通过usermodel请求下来的网络数据,由于M层和V层之间不能直接传递数据,所以,要将M层请求下来的数据 通过接口回调的方法传递到P层,所以接下来要定义一个接口
OnFinishLisenter:
package model; import java.util.List; import bean.User; /** * Created by 笔片 on 2017/11/7. */ public interface OnFinishLisenter { void OnFinish(List<User.SongListBean> list); }
接下来,就写中间层presenter,用来获取来自model层传过来的数据,并且发送给View层,
userPresenter.class:
package presenter; import java.util.List; import bean.User; import model.OnFinishLisenter; import model.usermodel; import view.Iview; /** * Created by 笔片 on 2017/11/7. */ public class userPresenter { Iview iview; usermodel usermodel; public userPresenter(final Iview iview) { this.iview = iview; this.usermodel = new usermodel(); usermodel.setLisenter(new OnFinishLisenter() { @Override public void OnFinish(List<User.SongListBean> list) { iview.GetUser(list); } }); } public void GetUrl(String url){ usermodel.GetJson(url); } }
由于要利用RecycleView来展示数据,来写适配器:
HomeAdapter.class:
package model; import android.content.Context; import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.bwie.test.mymvprxjavaretrofitrecycleview.R; import com.facebook.drawee.view.SimpleDraweeView; import java.util.List; import bean.User; /** * Created by 笔片 on 2017/11/7. */ public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{ List<User.SongListBean> mDatas; Context context; public HomeAdapter(List<User.SongListBean> mDatas, Context context) { this.mDatas = mDatas; this.context = context; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from( context).inflate(R.layout.list_item, parent, false)); return holder; } @Override public int getItemCount() { return mDatas.size(); } class MyViewHolder extends RecyclerView.ViewHolder { TextView tv; SimpleDraweeView img; public MyViewHolder(View view) { super(view); tv = (TextView) view.findViewById(R.id.tv); img = (SimpleDraweeView) view.findViewById(R.id.img); } } public interface OnItemClickLitener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } private OnItemClickLitener mOnItemClickLitener; public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { this.mOnItemClickLitener = mOnItemClickLitener; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { holder.tv.setText(mDatas.get(position).getTitle()); String url = mDatas.get(position).getPic_small(); Uri uri = Uri.parse(url); holder.img.setImageURI(uri); // if (url.equals("") || url == null) { // holder.img.setImageResource(R.mipmap.ic_launcher); // } else { // ImageLoader imgl = ImageLoader.getInstance(); // imgl.displayImage(url, holder.img); // } // 如果设置了回调,则设置点击事件 if (mOnItemClickLitener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos = holder.getLayoutPosition(); mOnItemClickLitener.onItemClick(holder.itemView, pos); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int pos = holder.getLayoutPosition(); mOnItemClickLitener.onItemLongClick(holder.itemView, pos); return false; } }); } } }
适配器中,加载图片的是用的fresco,要初始化,所以还是建了一个类,AppMy,用来初始化fresco
AppMy.class:
package app; import android.app.Application; import com.facebook.drawee.backends.pipeline.Fresco; /** * Created by 笔片 on 2017/11/7. */ public class AppMy extends Application{ @Override public void onCreate() { Fresco.initialize(this); } }
MainActivity.class:package com.bwie.test.mymvprxjavaretrofitrecycleview; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import java.util.List; import api.Api; import bean.User; import model.HomeAdapter; import presenter.userPresenter; import view.Iview; public class MainActivity extends AppCompatActivity implements Iview{ userPresenter presenter; RecyclerView recyclerView; HomeAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); presenter = new userPresenter(this); presenter.GetUrl(Api.URL_HOME); recyclerView = (RecyclerView) findViewById(R.id.revyvleview); } // 得到presenter传过来的数据,添加到输配器中 @Override public void GetUser(List<User.SongListBean> list) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new HomeAdapter(list,MainActivity.this); recyclerView.setAdapter(adapter); } }
布局文件:
mainactivity.xml:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.bwie.test.mymvprxjavaretrofitrecycleview.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/revyvleview" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </RelativeLayout>
子布局:
list_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/img"
android:layout_width="130dp"
android:layout_height="130dp"
fresco:placeholderImage="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="33333333333333333" />
</LinearLayout>
到这里就写完了,其中有不足的地方,还是要请多多指教。