Rxjava+Retrofit进行网络请求(已设置网络缓存),并结合我所阐述的XRecylerView配合使用,完成下拉刷新与上拉加载分页显示效果
Rxjava+Retrofit进行网络请求,并设置相关缓存,只需两个类XRecyclerView 下拉刷新与上拉加载 请看https://github.com/XRecyclerView/XRecyclerView第一步先在Module的build.gradle下添加相关依赖compile ‘io.reactivex:rxandroid:1.2.1’compile ‘com...
·
Rxjava+Retrofit进行网络请求,并设置相关缓存,只需两个类
XRecyclerView 下拉刷新与上拉加载 请看https://github.com/XRecyclerView/XRecyclerView
第一步先在Module的build.gradle下添加相关依赖
- compile ‘io.reactivex:rxandroid:1.2.1’
- compile ‘com.squareup.retrofit2:retrofit:2.1.0’
- compile ‘com.squareup.retrofit2:converter-gson:2.1.0’
- compile ‘com.squareup.retrofit2:adapter-rxjava:2.1.0’
- compile ‘com.squareup.retrofit2:converter-scalars:2.1.0’
RetrofitService
public interface RetrofitService {
@GET("data/product/index.php")
Observable<Product> getProduct();
@GET("data/product/list.php")
Observable<ProductList> getProductList(@Query("pno") int pageNumber,@Query("pageSize") int pageSize);
}
RetrofitManager
public class RetrofitManager {
private Context context;
private File httpCacheDirectory;
private int cacheSize = 10 * 1024 * 1024; // 10 MiB
private Cache cache;
private OkHttpClient client;
private Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR;
public RetrofitManager(Context context) {
this.context = context;
this.httpCacheDirectory=new File(context.getCacheDir(), "responses");
this.cache = new Cache(httpCacheDirectory, cacheSize);
this.REWRITE_CACHE_CONTROL_INTERCEPTOR=chain -> {
CacheControl.Builder cacheBuilder = new CacheControl.Builder();
cacheBuilder.maxAge(0, TimeUnit.SECONDS);
cacheBuilder.maxStale(365, TimeUnit.DAYS);
CacheControl cacheControl = cacheBuilder.build();
Request request = chain.request();
if (!NetworkUtils.isAvailable(context)) {
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
Response originalResponse = chain.proceed(request);
if (NetworkUtils.isAvailable(context)) {
int maxAge = 0; // read from cache
return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public ,max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
};
this.client=new OkHttpClient.Builder()
.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.cache(cache).build();
}
/**
* 配置网络缓存
*/
public final String API_BASE_URL = "http://192.168.10.100:80/ajia_code/";
private Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create());
public <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
}
}
NetworkUtils
public class NetworkUtils {
public static final int NETWORK_NO = -1; // no network
public static final int NETWORK_WIFI = 1; // wifi network
public static final int NETWORK_2G = 2; // "2G" networks
public static final int NETWORK_3G = 3; // "3G" networks
public static final int NETWORK_4G = 4; // "4G" networks
public static final int NETWORK_UNKNOWN = 5; // unknown network
private static final int NETWORK_TYPE_GSM = 16;
private static final int NETWORK_TYPE_TD_SCDMA = 17;
private static final int NETWORK_TYPE_IWLAN = 18;
/**
* 打开网络设置界面
* <p>3.0以下打开设置界面</p>
*
* @param context 上下文
*/
public static void openWirelessSettings(Context context) {
if (android.os.Build.VERSION.SDK_INT > 10) {
context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
} else {
context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
}
/**
* 获取活动网络信息
*
* @param context 上下文
* @return NetworkInfo
*/
private static NetworkInfo getActiveNetworkInfo(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
/**
* 判断网络是否可用
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return {@code true}: 可用<br>{@code false}: 不可用
*/
public static boolean isAvailable(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isAvailable();
}
/**
* 判断网络是否连接
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isConnected(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isConnected();
}
/**
* 判断网络是否是4G
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return {@code true}: 是<br>{@code false}: 不是
*/
public static boolean is4G(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isAvailable() && info.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE;
}
/**
* 判断wifi是否连接状态
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return {@code true}: 连接<br>{@code false}: 未连接
*/
public static boolean isWifiConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null && cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
}
/**
* 获取移动网络运营商名称
* <p>如中国联通、中国移动、中国电信</p>
*
* @param context 上下文
* @return 移动网络运营商名称
*/
public static String getNetworkOperatorName(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getNetworkOperatorName() : null;
}
/**
* 获取移动终端类型
*
* @param context 上下文
* @return 手机制式
* <ul>
* <li>{@link TelephonyManager#PHONE_TYPE_NONE } : 0 手机制式未知</li>
* <li>{@link TelephonyManager#PHONE_TYPE_GSM } : 1 手机制式为GSM,移动和联通</li>
* <li>{@link TelephonyManager#PHONE_TYPE_CDMA } : 2 手机制式为CDMA,电信</li>
* <li>{@link TelephonyManager#PHONE_TYPE_SIP } : 3</li>
* </ul>
*/
public static int getPhoneType(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getPhoneType() : -1;
}
/**
* 获取当前的网络类型(WIFI,2G,3G,4G)
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return 网络类型
* <ul>
* <li>{@link #NETWORK_WIFI } = 1;</li>
* <li>{@link #NETWORK_4G } = 4;</li>
* <li>{@link #NETWORK_3G } = 3;</li>
* <li>{@link #NETWORK_2G } = 2;</li>
* <li>{@link #NETWORK_UNKNOWN} = 5;</li>
* <li>{@link #NETWORK_NO } = -1;</li>
* </ul>
*/
public static int getNetWorkType(Context context) {
int netType = NETWORK_NO;
NetworkInfo info = getActiveNetworkInfo(context);
if (info != null && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
netType = NETWORK_WIFI;
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
switch (info.getSubtype()) {
case NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
netType = NETWORK_2G;
break;
case NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
netType = NETWORK_3G;
break;
case NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
netType = NETWORK_4G;
break;
default:
String subtypeName = info.getSubtypeName();
if (subtypeName.equalsIgnoreCase("TD-SCDMA")
|| subtypeName.equalsIgnoreCase("WCDMA")
|| subtypeName.equalsIgnoreCase("CDMA2000")) {
netType = NETWORK_3G;
} else {
netType = NETWORK_UNKNOWN;
}
break;
}
} else {
netType = NETWORK_UNKNOWN;
}
}
return netType;
}
/**
* 获取当前的网络类型(WIFI,2G,3G,4G)
* <p>依赖上面的方法</p>
*
* @param context 上下文
* @return 网络类型名称
* <ul>
* <li>NETWORK_WIFI </li>
* <li>NETWORK_4G </li>
* <li>NETWORK_3G </li>
* <li>NETWORK_2G </li>
* <li>NETWORK_UNKNOWN</li>
* <li>NETWORK_NO </li>
* </ul>
*/
public static String getNetWorkTypeName(Context context) {
switch (getNetWorkType(context)) {
case NETWORK_WIFI:
return "NETWORK_WIFI";
case NETWORK_4G:
return "NETWORK_4G";
case NETWORK_3G:
return "NETWORK_3G";
case NETWORK_2G:
return "NETWORK_2G";
case NETWORK_NO:
return "NETWORK_NO";
default:
return "NETWORK_UNKNOWN";
}
}
}
下拉刷新与上拉加载 用的我github上已经描述的XRecylerView
网络请求实现分页整体代码如下
public class TestRecylerViewActivity extends AppCompatActivity {
//初始化组件
@BindView(R.id.xrlv_recylerview)
XRecyclerView xrlvRecylerview;
//第一页
private int num=1;
private LinearLayoutManager llm;
private boolean flag;
private boolean tag;
private ListAdapter listAdapter;
private List<ProductList.DataBean> list;
/**
* retrofitService接口
*/
private RetrofitService rs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_recyler_view);
ButterKnife.bind(this);
llm=new LinearLayoutManager(this);
//设置chunzhi垂直布局
llm.setOrientation(LinearLayoutManager.VERTICAL);
xrlvRecylerview.setLayoutManager(llm);
//刷新时间可见
xrlvRecylerview.getDefaultRefreshHeaderView().setRefreshTimeVisible(true);
xrlvRecylerview.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);
xrlvRecylerview.setLoadingMoreProgressStyle(ProgressStyle.SquareSpin);
//添加横向分割线
xrlvRecylerview.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
//创建Retrofit
rs=new RetrofitManager(this).createService(RetrofitService.class);
startHttpRequest(num);
// xrlvRecylerview.setAdapter(listAdapter);
xrlvRecylerview.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
flag=true;
num=1;
startHttpRequest(num);
}
@Override
public void onLoadMore() {
flag=false;
num++;
startHttpRequest(num);
}
});
}
/**
* 发起网络请求
* @param pageNumber
*/
private void startHttpRequest(int pageNumber){
rs.getProductList(pageNumber,5).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<ProductList>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(ProductList productList) {
List<ProductList.DataBean> data = productList.getData();
if(flag==true){
list.clear();
list.addAll(0,data);
listAdapter.notifyDataSetChanged();
// listAdapter=new ListAdapter(list,TestRecylerViewActivity.this);
// xrlvRecylerview.setAdapter(listAdapter);
xrlvRecylerview.refreshComplete();
Log.d("tag1","刷新" +data.size()+" "+listAdapter.getItemCount());
}else{
if(tag==false){
list= data;
listAdapter=new ListAdapter(list,TestRecylerViewActivity.this);
xrlvRecylerview.setAdapter(listAdapter);
tag=true;
Log.d("tag2","首部加载"+data.size()+" "+listAdapter.getItemCount());
}else {
list.addAll(data);
listAdapter.notifyDataSetChanged();
//xrlvRecylerview.setAdapter(new ListAdapter(list,TestRecylerViewActivity.this));
xrlvRecylerview.loadMoreComplete();
Log.d("tag3","尾部加载"+data.size()+" "+listAdapter.getItemCount());
}
}
}
});
}
}
相关布局
<?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.example.yanruifeng.myapplication.TestRecylerViewActivity">
<com.jcodecraeer.xrecyclerview.XRecyclerView
android:id="@+id/xrlv_recylerview"
android:layout_width="match_parent"
android:layout_height="match_parent"></com.jcodecraeer.xrecyclerview.XRecyclerView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_toRightOf="@id/tv_title"
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:layout_below="@id/tv_price"
android:id="@+id/iv_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
适配器
public class ListAdapter extends RecyclerView.Adapter {
private List<ProductList.DataBean> list;
private Context context;
public ListAdapter(List<ProductList.DataBean> list, Context context) {
this.list = list;
this.context = context;
Log.d("tag",list.size()+"");
}
public ListAdapter(){
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.recylerview_item,parent,false);
ViewHolder holder=new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder viewHolder= (ViewHolder) holder;
viewHolder.tvTitle.setText(list.get(position).getTitle());
viewHolder.tvPrice.setText(list.get(position).getPrice());
Glide.with(context).load(HttpUrl.IP+"/"+list.get(position).getPic()).into(viewHolder.ivPic);
}
@Override
public int getItemCount() {
return list==null?0:list.size();
}
static class ViewHolder extends RecyclerView.ViewHolder{
public TextView tvTitle;
public TextView tvPrice;
public ImageView ivPic;
public ViewHolder(View itemView) {
super(itemView);
tvTitle=itemView.findViewById(R.id.tv_title);
tvPrice=itemView.findViewById(R.id.tv_price);
ivPic=itemView.findViewById(R.id.iv_pic);
}
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献6条内容
所有评论(0)