此文主要实现两方面功能:
1 设置Picasso的缓存路径---默认Picasso的缓存都是在内置存储的cache路径下,如果下载较大图片则会导致下载不成功,但是系统也没有报错 坑。。。
2 Picasso下载图片时,自带下载进度提示,当下载完成时显示图片,如下图所示:
完整代码在这:http://download.csdn.net/detail/zxm317122667/9566123
接下来说下实现步骤:
1 导入依赖库
众所周知,Picasso内部网络请求使用的是OkHttp,而Picasso和OkHttp都是一家叫做Square的公司的亲儿子。因此我们要重新设置Picasso网络请求实现,需要将这两个包都添加到依赖中,在build.gradle中添加如下代码:
repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
maven {
url "http://maven.bughd.com/public"
}
}
compile "com.squareup.picasso:picasso:2.5.3-SNAPSHOT"
compile 'com.squareup.okhttp3:okhttp:3.3.1'
以上代码中,注意 Picasso的依赖一定要是comple "com.squareup.picasso:picasso:2.5.3-SNAPSHOT"
2 获取Picasso
重写OkHttp的Client类,并将重写的Client传递给自定义的Picasso,代码如下:
package material.danny_jiang.com.picassosenior.utils;
import android.content.Context;
import android.support.annotation.IntRange;
import android.support.annotation.WorkerThread;
import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
import java.io.File;
import java.io.IOException;
import material.danny_jiang.com.picassosenior.MyApplication;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/**
* Created by axing on 16/7/2.
*/
public class SquareUtils {
static private OkHttpClient client;
static public synchronized OkHttpClient getClient() {
if (client == null) {
final File cacheDir = MyApplication.getInstance().getExternalCacheDir();
client = new OkHttpClient.Builder()
//Interceptor -> cache -> NetworkInterceptor
//.addNetworkInterceptor(getLogger())
.cache(new Cache(new File(cacheDir, "okhttp"), 60 * 1024 * 1024))
//.dispatcher(getDispatcher())
//.dns(HTTP_DNS)
.build();
}
return client;
}
/**
* Not singleton
*/
private static OkHttpClient getProgressBarClient(final ProgressListener listener) {
return getClient().newBuilder().addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), listener))
.build();
}
}).build();
}
/**
* Download Big Image only, Not singleton but shared cache
*/
static public Picasso getPicasso(Context context, ProgressListener listener) {
OkHttpClient client = getProgressBarClient(listener);
OkHttp3Downloader downloader = new OkHttp3Downloader(client);
return new Picasso.Builder(context).downloader(downloader)
.memoryCache(com.squareup.picasso.Cache.NONE)
.build();
}
public interface ProgressListener {
@WorkerThread
void update(@IntRange(from = 0, to = 100) int percent);
}
private static class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final ProgressListener progressListener;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
this.responseBody = responseBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
if (progressListener != null) {
progressListener.update(
((int) ((100 * totalBytesRead) / responseBody.contentLength())));
}
return bytesRead;
}
};
}
}
}
3 自定义ImageView, 实现饼状图的绘制
package material.danny_jiang.com.picassosenior.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.IntRange;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Created by axing on 3/7/16.
* Image with Pie Progress
* learned from com.kaopiz.kprogresshud's PieView
*/
public class PieImageView extends ImageView {
private final int MAX_PROGRESS = 100;
private Paint mArcPaint;
private RectF mBound;
private Paint mCirclePaint;
private int mProgress = 0;
public PieImageView(Context context) {
this(context, null, 0);
}
public PieImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PieImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void setProgress(@IntRange(from = 0, to = MAX_PROGRESS) int mProgress) {
this.mProgress = mProgress;
ViewCompat.postInvalidateOnAnimation(this);
}
private void init() {
mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArcPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mArcPaint.setStrokeWidth(dpToPixel(0.1f, getContext()));
//mArcPaint.setColor(Color.argb(120, 0xff, 0xff, 0xff));
mArcPaint.setColor(Color.RED);
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setStyle(Paint.Style.STROKE);
mCirclePaint.setStrokeWidth(dpToPixel(2, getContext()));
mCirclePaint.setColor(Color.argb(120, 0xff, 0xff, 0xff));
mBound = new RectF();
}
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int min = Math.min(w, h);
int max = w + h - min;
int r = min / 5;
//set up a square in the imageView
mBound.set(max / 2 - r, min / 2 - r, max / 2 + r, min / 2 + r);
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mProgress != MAX_PROGRESS && mProgress != 0) {
float mAngle = mProgress * 360f / MAX_PROGRESS;
canvas.drawArc(mBound, 270, mAngle, true, mArcPaint);
canvas.drawCircle(mBound.centerX(), mBound.centerY(), mBound.height() / 2, mCirclePaint);
}
}
private float scale = 0;
private int dpToPixel(float dp, Context context) {
if (scale == 0) {
scale = context.getResources().getDisplayMetrics().density;
}
return (int) (dp * scale);
}
}
打完 收功!