RecyclerView 實現listview和gridview佈局(各自的子佈局不同,網路資料)
阿新 • • 發佈:2019-02-15
- 匯入依賴:(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);
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(Context 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