一、基本使用
//添加依赖(build.gradle)
implementation 'com.squareup.picasso:picasso:2.5.2'
//添加网络权限(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET"/>
//加载网络图片(MainActivity)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.into(imageView);
}
}
//加载Uri路径的图片(MainActivity)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
ImageView imageView = findViewById(R.id.imageview);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.mipmap.ic_launcher);
Picasso.with(this)
.load(uri)
.into(imageView);
}
}
//加载本地资源图片(MainActivity)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(R.mipmap.ic_launcher)
.into(imageView);
}
}
//加载File中的图片(MainActivity)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String path = getExternalCacheDir().getAbsoluteFile() + File.separator + "ic_launcher.png";
Log.d(TAG, "zwm, path: " + path);
File file = new File(path);
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(file)
.into(imageView);
}
}
二、placeholder & error & noPlaceholder & noFade
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
//.noPlaceholder() //不显示占位图
.error(R.mipmap.ic_launcher_round) //加载出错时显示的图片
.noFade() //不显示渐入效果
.into(imageView);
}
}
三、Resize(设置图片尺寸) & Scale(缩放) & Crop(裁剪)
resize(int targetWidth, int targetHeight),以px为单位
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.resize(200,200)
.into(imageView);
}
}
resizeDimen(int targetWidthResId, int targetHeightResId),以dp为单位
//dimens.xml
<resources>
<dimen name="image_width">200dp</dimen>
<dimen name="image_height">200dp</dimen>
</resources>
//MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.resizeDimen(R.dimen.image_width, R.dimen.image_height)
.into(imageView);
}
}
onlyScaleDown()
当调用resize方法重新设置图片尺寸,并调用了onlyScaleDown方法,只有当原始图片的尺寸大于我们指定的尺寸时,resize才起作用。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.resize(200,200)
.onlyScaleDown()
.into(imageView);
}
}
centerCrop()
充满View边界,居中裁剪。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.resize(200,200)
.centerCrop()
.into(imageView);
}
}
centerInside()
centerCrop是可能看不到全部图片的,如果想让View将图片完全展示,可以用centerInside。但是如果图片尺寸小于View尺寸的话,是不能充满View边界的。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.resize(200,200)
.centerInside()
.into(imageView);
}
}
fit()
充满View边界,有可能会出现拉伸扭曲的情况。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.fit()
.into(imageView);
}
}
四、Rotate(旋转)
rotate(float degrees)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.rotate(180)
.into(imageView);
}
}
rotate(float degrees, float pivotX, float pivotY)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.rotate(90, 200, 100)
.into(imageView);
}
}
五、Transformation(转换器)
Transformation是Picasso的一个非常强大的功能,它允许在加载图片的过程中对图片做一系列的变换,如高斯模糊、添加圆角、度灰处理、圆形图片等。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.transform(new BlurTransformation(this))
.transform(new GrayTransformation())
.into(imageView);
}
//高斯模糊
private static class BlurTransformation implements Transformation {
RenderScript rs;
public BlurTransformation(Context context) {
super();
rs = RenderScript.create(context);
}
@Override
public Bitmap transform(Bitmap bitmap) {
// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED);
Allocation output = Allocation.createTyped(rs, input.getType());
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);
// Set the blur radius
script.setRadius(25);
// Start the ScriptIntrinisicBlur
script.forEach(output);
// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);
bitmap.recycle();
return blurredBitmap;
}
@Override
public String key() {
return "blur";
}
}
//度灰
private static class GrayTransformation implements Transformation{
@Override
public Bitmap transform(Bitmap source) {
int width, height;
height = source.getHeight();
width = source.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(source, 0, 0, paint);
if(source!=null && source!=bmpGrayscale){
source.recycle();
}
return bmpGrayscale;
}
@Override
public String key() {
return "gray";
}
}
}
或者:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
List<Transformation> transformations = new ArrayList<>();
transformations.add(new GrayTransformation());
transformations.add(new BlurTransformation(this));
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher) //占位图
.transform(transformations)
.into(imageView);
}
//高斯模糊
private static class BlurTransformation implements Transformation {
RenderScript rs;
public BlurTransformation(Context context) {
super();
rs = RenderScript.create(context);
}
@Override
public Bitmap transform(Bitmap bitmap) {
// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED);
Allocation output = Allocation.createTyped(rs, input.getType());
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);
// Set the blur radius
script.setRadius(25);
// Start the ScriptIntrinisicBlur
script.forEach(output);
// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);
bitmap.recycle();
return blurredBitmap;
}
@Override
public String key() {
return "blur";
}
}
//度灰
private static class GrayTransformation implements Transformation{
@Override
public Bitmap transform(Bitmap source) {
int width, height;
height = source.getHeight();
width = source.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(source, 0, 0, paint);
if(source!=null && source!=bmpGrayscale){
source.recycle();
}
return bmpGrayscale;
}
@Override
public String key() {
return "gray";
}
}
}
六、请求优先级
Picasso为请求设置有优先级,有三种优先级:LOW、NORMAL、HIGH,默认情况下都是NORMAL,但是fetch方法除外,fetch方法的优先级是LOW。
可以通过priority方法设置请求的优先级,这会影响请求的执行顺序,但是这是不能保证的,它只会往高的优先级靠拢。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher)
.priority(Picasso.Priority.HIGH)
.into(imageView);
}
}
七、Tag管理请求
Picasso#
- cancelTag(Object tag):取消设置了给定tag的所有请求。
- pauseTag(Object tag):暂停设置了给定tag的所有请求。
- resumeTag(Object tag):resume被暂停的给定tag的所有请求。
RequestCreator#
- tag(Object tag):为请求设置tag。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
ImageView imageView = findViewById(R.id.imageview);
Picasso.with(this)
.load(url)
.placeholder(R.mipmap.ic_launcher)
.tag("PhotoTag")
.into(imageView);
}
}
使用场景1:快速滑动列表时暂停请求
//Adapter
Picasso.with(this).load(mData.get(position))
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.tag("PhotoTag")
.into(holder.mImageView);
//Activity
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
final Picasso picasso = Picasso.with(MainActivity.this);
if (newState == SCROLL_STATE_IDLE) {
picasso.resumeTag("PhotoTag");
} else {
picasso.pauseTag("PhotoTag");
}
}
});
使用场景2:退出界面取消请求
@Override
protected void onDestroy() {
super.onDestroy();
Picasso.with(this).cancelTag("PhotoTag");
}
八、同步/异步加载图片
同步:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
final String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
new Thread(new Runnable() {
@Override
public void run() {
try {
Bitmap bitmap = Picasso.with(MainActivity.this).load(url).get();
Log.d(TAG, "zwm, bitmap: " + bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
异步:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
//Picasso.with(MainActivity.this).load(url).fetch();
Picasso.with(MainActivity.this).load(url).fetch(new Callback() {
@Override
public void onSuccess() {
Log.d(TAG, "zwm, onSuccess");
}
@Override
public void onError() {
Log.d(TAG, "zwm, onError");
}
});
}
}
九、缓存
内存缓存是使用LRU策略的缓存实现,它的大小是内存大小的15%。磁盘缓存的大小是磁盘容量的2%,并且不超过50M、不少于5M。
处理一个请求时,按照顺序检查:memory -> disk -> network。
默认情况下,Picasso内存缓存和磁盘缓存都是开启了的,但是有些时候,我们并不需要缓存,比如加载一张大图片的时候,如果在内存中保存一份,很容易造成OOM,这时候我们只希望有磁盘缓存,而不希望缓存到内存,因此就需要我们设置缓存策略了。
设置内存缓存策略:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
ImageView imageView = findViewById(R.id.imageview);
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
Picasso.with(MainActivity.this)
.load(url)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
}
}
设置磁盘缓存策略:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
ImageView imageView = findViewById(R.id.imageview);
String url = "http://img1.imgtn.bdimg.com/it/u=1447234934,94659509&fm=26&gp=0.jpg";
Picasso.with(MainActivity.this)
.load(url)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) //注意:NetworkPolicy.NO_STORE只对OkHttp有效
//.networkPolicy(NetworkPolicy.OFFLINE) //只从缓存获取结果,不发起网络请求
.into(imageView);
}
}
十、Debug和日志
缓存指示器:
在图片的左上角出现一个带色块的三角形标示,有3种颜色,绿色表示从内存加载、蓝色表示从磁盘加载、红色表示从网络加载。
Picasso.with(this).setIndicatorsEnabled(true);
日志:
Picasso可以打印一些日志,比如一些关键方法的执行时间等。
Picasso.with(this).setLoggingEnabled(true);
十一、Picasso扩展
- 用Builder自己构造一个Picasso实例。
- 配置自定义下载器DownLoader。
- 配置缓存。
- 配置线程池。
- 配置全局的Picasso实例。
//Application
@Override
public void onCreate() {
super.onCreate();
//配置全局的Picasso实例
Picasso.Builder builder = new Picasso.Builder(this);
//配置下载器
builder.downloader(new CustomDownloader());
//配置缓存
LruCache cache = new LruCache(5*1024*1024); //设置缓存大小
builder.memoryCache(cache);
//配置线程池
ExecutorService executorService = Executors.newFixedThreadPool(8);
builder.executor(executorService);
//构造一个Picasso
Picasso picasso = builder.build();
//设置全局的Picasso实例
Picasso.setSingletonInstance(picasso);
}
//Activity
Picasso.with(MainActivity.this)
.load(url)
.into(imageView);