您的位置:首页 > 理论基础 > 计算机网络

RecyclerView 实现listview和gridview布局(各自的子布局不同,网络数据)

2017-10-14 14:03 561 查看
导入依赖:(app的build.gradle中)
MainActivity的布局:
写子页面布局:
写分割线的类:
注册Myapp类,同时写一个单例,以节省资源,并初始化
使用已经封装好的OkHttp3的Utils
在MainActivity中判断网络状态
initView方法:
添加RecyclerView的适配器(内部类):
最终的效果图,有些图片没有出来,接口的问题:

1.导入依赖:(app的build.gradle中)

dependencies {
/*recyclerview*/
compile 'com.github.liuguangqiang.SuperRecyclerView:super-recyclerview:0.1.2'
/*imgageloader*/
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'

/*okhttp3导入依赖*/
compile 'com.squareup.okio:okio:1.5.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.google.code.gson:gson:2.8.2'
/*Logger依赖*/
compile 'com.orhanobut:logger:1.15'}
}

2.MainActivity的布局:

<LinearLayout
android:id="@+id/searchLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_marginLeft="5dp"
android:id="@+id/change"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="视图切换"
/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_below="@+id/searchLayout"
android:id="@+id/recyclerview"
android:divider="#ffff0000"
android:dividerHeight="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />

3.写子页面布局:

样式一:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/goodsimg"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="标题111111111"
android:textSize="15dp"
android:textStyle="bold"
/>
<TextView
android:layout_marginTop="40dp"
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="价格:"
android:textStyle="bold"
/>
</LinearLayout>

</LinearLayout>
样式二:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/goodsimg"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="标题111111111"
android:textSize="15dp"
android:textStyle="bold"
/>
<TextView
android:layout_marginTop="40dp"
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="价格:"
android:textStyle="bold"
/>
</LinearLayout>

</LinearLayout>


4.写分割线的类:

DividerItemDecoration

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
* Created by xue on 2017-10-14.
*/

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};

public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

private Drawable mDivider;

private int mOrientation;

public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}

public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}

@Override
public void onDraw(Canvas c, RecyclerView parent) {

if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}

}

public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);

4000
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}

}
5.注册Myapp类,同时写一个单例,以节省资源,并初始化imageLoader

import android.app.Application;

import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

/**
* Created by xue on 2017-10-14.
*/
//写个单例,节省资源
public class MyApp extends Application{

public static MyApp mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
//初始化imageloader
ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(getApplicationContext());
ImageLoader.getInstance().init(configuration);
}
public static MyApp getInstance() {
return mInstance;
}
}

6.使用已经封装好的OkHttp3的Utils



7.在MainActivity中判断网络状态

/*判断网络状态*/
private void initNet() {
boolean netWorkAvailable = NetWorkUtils.isNetWorkAvailable(this);
if (!netWorkAvailable){
Toast.makeText(BuySearchActivity.this, "联网:" + netWorkAvailable, Toast.LENGTH_SHORT).show();
}
/*请求网络数据*/
getData();
}
记得请求网络数据需要添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
接下来用GsonFormat生成bean类,然后得到网络数据:
//得到网路数据
public void getData() {

OkHttp3Utils.getInstance().doGet(path, new GsonObjectCallback<SuperClass>() {

@Override
public void onUi(SuperClass superClass) {
newslist = superClass.getNewslist();
list = new ArrayList<SuperClass.NewslistBean>();
list= (ArrayList<SuperClass.NewslistBean>) newslist;
}

@Override
public void onFailed(Call call, IOException e) {

}
});
}

8.initView方法:

private void initView() {

recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
change = (Button) findViewById(R.id.change);
/*listview*/
recyclerview.setLayoutManager(new LinearLayoutManager(this));
myAdapter = new MyAdapter();
recyclerview.setAdapter(myAdapter);
/*分割线*/
recyclerview.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.HORIZONTAL_LIST));
recyclerview.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL_LIST));

//改变视图样式
change.setOnClickListener(new View.OnClickListener() {
boolean flag = false;
// 利用开关切换recyclerview的布局
@Override
public void onClick(View v) {
if (flag){
type=1;
recyclerview.setLayoutManager(new LinearLayoutManager(BuySearchActivity.this));
flag=false;
}else{
type=2;
recyclerview.setLayoutManager(new GridLayoutManager(BuySearchActivity.this,2));
flag=true;
}
}
});
}

9.添加RecyclerView的适配器(内部类):

int type = 1;

建一个type来区分一下子布局的样式

/*适配器*/
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
{

private MyViewHolder holder;

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
if (viewType==1){

holder =  new MyViewHolder(LayoutInflater.from(
BuySearchActivity.this).inflate(R.layout.itemone, parent,
false));
}else{
holder = new MyViewHolder(LayoutInflater.from(
BuySearchActivity.this).inflate(R.layout.itemtwo, parent,
false));
}

return holder;
}

@Override
public int getItemViewType(int position) {
return type;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
holder.title.setText(list.get(position).getTitle());
ImageLoader.getInstance().displayImage(list.get(position).getPicUrl(),holder.goodsimg);
holder.price.setText(list.get(position).getCtime());
}

@Override
public int getItemCount()
{
return list==null?0:list.size();
}

class MyViewHolder extends RecyclerView.ViewHolder
{

TextView title;
ImageView goodsimg;
TextView price;

public MyViewHolder(View view) {
super(view); title = (TextView) view.findViewById(R.id.title);
goodsimg = (ImageView) view.findViewById(R.id.goodsimg);
price = (TextView) view.findViewById(R.id.price);
}

}
}

10.最终的效果图,有些图片没有出来,接口的问题:



如果要实现多条目,只需要重写

@Override
public int getItemViewType(int position) {
return position%2;
}


效果:



最后再添加点击事件:

写接口回调类:
public interface ItemClickLitener {

void onItemClick(View view, int position);

void onItemLongClick(View view, int position);

//    Item 内部View点击
public void onItemSubViewClick(View view, int postion);
}
在适配器内:
private ItemClickLitener mItemClickListener;
public void setItemClickListener(ItemClickLitener mItemClickListener) {
this.mItemClickListener = mItemClickListener;

}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position)
{
holder.title.setText(list.get(position).getTitle());
ImageLoader.getInstance().displayImage(list.get(position).getPicUrl(),holder.goodsimg);
holder.price.setText(list.get(position).getCtime());
// 为图片添加监听回调
            holder.goodsimg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (null != mItemClickListener) {
                        /*点击图片*/
                        mItemClickListener.onItemSubViewClick(holder.goodsimg,position);
                    }
                }
            });
        }
}

class MyViewHolder extends RecyclerView.ViewHolder
{

TextView title;
ImageView goodsimg;
TextView price;

public MyViewHolder(final View view) {
super(view); title = (TextView) view.findViewById(R.id.title);
goodsimg = (ImageView) view.findViewById(R.id.goodsimg);
price = (TextView) view.findViewById(R.id.price);

//为item添加普通点击回调
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mItemClickListener) {
mItemClickListener.onItemClick(view, getPosition());
}
}
});

/* 长按回调*/
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (null != mItemClickListener) {
mItemClickListener.onItemLongClick(view, getPosition());
}
return true;
}
});
}

}
最后在initView方法中调用
/*条目点击事件*/
myAdapter.setItemClickListener(new ItemClickLitener() {
@Override
public void onItemClick(View view, int postion) {
Toast.makeText(BuySearchActivity.this,"点击了item"+postion,Toast.LENGTH_SHORT).show();
}

@Override
public void onItemLongClick(View view, int postion) {
Toast.makeText(BuySearchActivity.this,"长按了item"+postion,Toast.LENGTH_SHORT).show();
}

@Override
public void onItemSubViewClick(View view, int postion) {
Toast.makeText(BuySearchActivity.this,"点击了img"+postion,Toast.LENGTH_SHORT).show();
}
});
最后是点击事件的效果图:



最后是工具类的代码:

GsonArrayCallback

import android.os.Handler;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
* 1. 类的用途 如果要将得到的json直接转化为集合 建议使用该类
* 该类的onUi() onFailed()方法运行在主线程
* 2. @author forever
* 3. @date 2017/9/24 18:47
*/

public abstract class GsonArrayCallback<T> implements Callback {
private Handler handler = OkHttp3Utils.getInstance().getHandler();

//主线程处理
public abstract void onUi(List<T> list);

//主线程处理
public abstract void onFailed(Call call, IOException e);

//请求失败
@Override
public void onFailure(final Call call, final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onFailed(call, e);
}
});
}

//请求json 并直接返回集合 主线程处理
@Override
public void onResponse(Call call, Response response) throws IOException {
final List<T> mList = new ArrayList<T>();

String json = response.body().string();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();

Gson gson = new Gson();

Class<T> cls = null;
Class clz = this.getClass();
ParameterizedType type = (ParameterizedType) clz.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
cls = (Class<T>) types[0];

for(final JsonElement elem : array){
//循环遍历把对象添加到集合
mList.add((T) gson.fromJson(elem, cls));
}

handler.post(new Runnable() {
@Override
public void run() {
onUi(mList);

}
});

}
}
GsonObjectCallback

import android.os.Handler;

import com.google.gson.Gson;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
* 1. 类的用途 如果要将得到的json直接转化为集合 建议使用该类
* 该类的onUi() onFailed()方法运行在主线程
* 2. @author forever
* 3. @date 2017/9/24 18:47
*/

public abstract class GsonObjectCallback<T> implements Callback {
private Handler handler = OkHttp3Utils.getInstance().getHandler();

//主线程处理
public abstract void onUi(T t);

//主线程处理
public abstract void onFailed(Call call, IOException e);

//请求失败
@Override
public void onFailure(final Call call, final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onFailed(call, e);
}
});
}

//请求json 并直接返回泛型的对象 主线程处理
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
Class<T> cls = null;

Class clz = this.getClass();
ParameterizedType type = (ParameterizedType) clz.getGenericSuperclass();
Type[] types = type.getActualTypeArguments();
cls = (Class<T>) types[0];
Gson gson = new Gson();
final T t = gson.fromJson(json, cls);
handler.post(new Runnable() {
@Override
public void run() {
onUi(t);
}
});
}
}
NetWorkUtils

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

/**
* 1. 类的用途 联网判断
* 2. @author forever
* 3. @date 2017/9/8 12:30
*/

public class NetWorkUtils {
//判断网络是否连接
public static boolean isNetWorkAvailable(Cont
e0c4
ext context) {
//网络连接管理器
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//网络信息
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null) {
return true;
}

return false;
}

}
OkHttp3Utils

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.bway.www.MyApp;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;

/**
* 1. 类的用途 封装OkHttp3的工具类 用单例设计模式
* 2. @author forever
* 3. @date 2017/9/6 09:19
*/

public class OkHttp3Utils {
/**
* 懒汉 安全 加同步
* 私有的静态成员变量 只声明不创建
* 私有的构造方法
* 提供返回实例的静态方法
*/

private static OkHttp3Utils okHttp3Utils = null;

private OkHttp3Utils() {
}

public static OkHttp3Utils getInstance() {
if (okHttp3Utils == null) {
//加同步安全
synchronized (OkHttp3Utils.class) {
if (okHttp3Utils == null) {
okHttp3Utils = new OkHttp3Utils();
}
}

}

return okHttp3Utils;
}

private static OkHttpClient okHttpClient = null;

public synchronized static OkHttpClient getOkHttpClient() {
if (okHttpClient == null) {
//判空 为空创建实例
// okHttpClient = new OkHttpClient();
/**
* 和OkHttp2.x有区别的是不能通过OkHttpClient直接设置超时时间和缓存了,而是通过OkHttpClient.Builder来设置,
* 通过builder配置好OkHttpClient后用builder.build()来返回OkHttpClient,
* 所以我们通常不会调用new OkHttpClient()来得到OkHttpClient,而是通过builder.build():
*/
//  File sdcache = getExternalCacheDir();
//缓存目录
File sdcache = new File(Environment.getExternalStorageDirectory(), "cache");
int cacheSize = 10 * 1024 * 1024;
//OkHttp3拦截器
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("xxx", message.toString());
}
});
//Okhttp3的拦截器日志分类 4种
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
//添加OkHttp3的拦截器
.addInterceptor(httpLoggingInterceptor)
.addNetworkInterceptor(new CacheInterceptor())
.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)
.cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))
.build();
}
return okHttpClient;
}

private static Handler mHandler = null;

public synchronized static Handler getHandler() {
if (mHandler == null) {
mHandler = new Handler();
}

return mHandler;
}

/**
* get请求
* 参数1 url
* 参数2 回调Callback
*/

public static void doGet(String url, Callback callback) {

//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getOkHttpClient();
//创建Request
Request request = new Request.Builder().url(url).build();
//得到Call对象
Call call = okHttpClient.newCall(request);
//执行异步请求
call.enqueue(callback);

}

/**
* post请求
* 参数1 url
* 参数2 回调Callback
*/

public static void doPost(String url, Map<String, String> params, Callback callback) {

//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getOkHttpClient();
//3.x版本post请求换成FormBody 封装键值对参数

FormBody.Builder builder = new FormBody.Builder();
//遍历集合
for (String key : params.keySet()) {
builder.add(key, params.get(key));

}

//创建Request
Request request = new Request.Builder().url(url).post(builder.build()).build();

Call call = okHttpClient.newCall(request);
call.enqueue(callback);

}

/**
* post请求上传文件
* 参数1 url
* 参数2 回调Callback
*/
public static void uploadPic(String url, File file, String fileName) {
//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getOkHttpClient();
//创建RequestBody 封装file参数
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//创建RequestBody 设置类型等
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", fileName, fileBody).build();
//创建Request
Request request = new Request.Builder().url(url).post(requestBody).build();

//得到Call
Call call = okHttpClient.newCall(request);
//执行请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {

}

@Override
public void onResponse(Call call, Response response) throws IOException {
//上传成功回调 目前不需要处理
}
});

}

/**
* Post请求发送JSON数据
* 参数一:请求Url
* 参数二:请求的JSON
* 参数三:请求回调
*/
public static void doPostJson(String url, String jsonParams, Callback callback) {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
Request request = new Request.Builder().url(url).post(requestBody).build();
Call call = getOkHttpClient().newCall(request);
call.enqueue(callback);

}

/**
* 下载文件 以流的形式把apk写入的指定文件 得到file后进行安装
* 参数一:请求Url
* 参数二:保存文件的路径名
* 参数三:保存文件的文件名
*/
public static void download(final Context context, final String url, final String saveDir) {
Request request = new Request.Builder().url(url).build();
Call call = getOkHttpClient().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("xxx", e.toString());
}

@Override
public void onResponse(Call call, final Response response) throws IOException {

InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();
//apk保存路径
final String fileDir = isExistDir(saveDir);
//文件
File file = new File(fileDir, getNameFromUrl(url));
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.flush();
//apk下载完成后 调用系统的安装方法
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) is.close();
if (fos != null) fos.close();

}
}
});

}

/**
* @param saveDir
* @return
* @throws IOException 判断下载目录是否存在
*/
public static String isExistDir(String saveDir) throws IOException {
// 下载位置
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
if (!downloadFile.mkdirs()) {
downloadFile.createNewFile();
}
String savePath = downloadFile.getAbsolutePath();
Log.e("savePath", savePath);
return savePath;
}
return null;
}

/**
* @param url
* @return 从下载连接中解析出文件名
*/
private static String getNameFromUrl(String url) {
return url.substring(url.lastIndexOf("/") + 1);
}

/**
* 为okhttp添加缓存,这里是考虑到服务器不支持缓存时,从而让okhttp支持缓存
*/
private static class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
// 有网络时 设置缓存超时时间1个小时
int maxAge = 60 * 60;
// 无网络时,设置超时为1天
int maxStale = 60 * 60 * 24;
Request request = chain.request();
if (NetWorkUtils.isNetWorkAvailable(MyApp.getInstance())) {
//有网络时只从网络获取
request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
} else {
//无网络时只从缓存中读取
request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
/* Looper.prepare();
Toast.makeText(MyApp.getInstance(), "走拦截器缓存", Toast.LENGTH_SHORT).show();
Looper.loop();*/
}
Response response = chain.proceed(request);
if (NetWorkUtils.isNetWorkAvailable(MyApp.getInstance())) {
response = response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
response = response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return response;
}
}
}
参考了鸿洋的博客:http://blog.csdn.net/lmj623565791/article/details/45059587








                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: