Android Picasso教程
Android Picasso是一个功能强大的图像下载和缓存库。
在本教程中,我们将在android应用程序中讨论和实现Picasso库。
Android毕加索
Android Picasso是由Square Inc开发和维护的图像加载/处理库。
由于它通常只需要一行代码并且每个功能都具有相似的编码风格,因此它非常受欢迎(我们将很快实现它们!) 。
要在Android Studio项目中使用android Picasso库,请在您的build.gradle文件中添加以下依赖项。
compile 'com.squareup.picasso:picasso:2.5.2'
Android Picasso带有自己的一组功能,例如:
- 调整大小和缩放
- 中心裁剪
- 旋转与变换
- 设置占位符和错误图像
- 衰退
- 磁盘和内存缓存
- 优先要求
- 支持取消请求和并行下载
Android Picasso –从URL加载图像
要使用picasso api从ImageView中的URL加载图像,通常使用以下代码段。
Picasso.with(context).load("https://cdn.theitroad.local/wp-content/uploads/2015/11/android-image-picker-project-structure.png").into(imageView)
Android Picasso –加载资源
加载资源(可绘制/mipmap):
Picasso.with(context).load(R.mipmap.ic_launcher).into(imageView);
Android Picasso –从文件加载图像
加载文件图像:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Sample.jpg"); Picasso.with(context).load(file).into(imageView);
Android Picasso缓存
- 内存策略
默认情况下,毕加索会尝试先从内存中获取图像。
为了防止这种情况,我们可以通过调用枚举MemoryPolicy.NO_CAHE,MemoryPolicy.NO_STORE中的一个或者两个来添加方法" noMemoryPolicy()"。
Memory.NO_CACHE用于防止从存储的缓存中加载图像。
Memory.NO_STORE用于根本不将图像存储在缓存中。
通常用于一次需要图像的情况。
Picasso.with(context).load(image_url).memoryPolicy(MemoryPolicy.NO_CACHE).into(imageView);
Picasso.with(context).load(image_url).memoryPolicy(MemoryPolicy.NO_STORE).into(imageView);
- 网络策略
如果未从内存中提供/阻止该图像,则Picasso接下来将尝试从磁盘缓存中获取它。
要跳过磁盘缓存,我们需要使用参数设置为NetworkPolicy.NO_CACHE来调用.networkPolicy()方法。
另一个有用的枚举是NetworkPolicy.OFFLINE,它将仅检查缓存中的图像。
它会显示错误图片(如果已定义)或者空白(如果在缓存中找不到该图片)。
Picasso.with(context).load(image_url).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
让我们深入研究android picasso教程的编码部分,其中我们将一起看到并实现所有功能。
Android Picasso示例代码
下面给出了" activity_main.xml"。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.theitroad.picassotutorial.MainActivity">
<Button
android:text="Drawable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/btnDrawable"
<ImageView
android:id="@+id/imageView"
android:src="@mipmap/ic_launcher"
android:layout_width="200dp"
android:layout_centerHorizontal="true"
android:layout_height="200dp"
<Button
android:text="Placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnPlaceholder"
android:layout_alignBaseline="@+id/btnUrl"
android:layout_alignBottom="@+id/btnUrl"
android:layout_centerHorizontal="true"
<Button
android:text="URL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnUrl"
android:layout_alignBaseline="@+id/btnDrawable"
android:layout_alignBottom="@+id/btnDrawable"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
<Button
android:text="Error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnError"
android:layout_below="@+id/btnDrawable"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="@dimen/activity_horizontal_margin"
<Button
android:text="Callback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnCallBack"
android:layout_alignBaseline="@+id/btnError"
android:layout_alignBottom="@+id/btnError"
android:layout_alignLeft="@+id/btnPlaceholder"
android:layout_alignStart="@+id/btnPlaceholder"
<Button
android:text="Resize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnResize"
android:layout_alignBaseline="@+id/btnCallBack"
android:layout_alignBottom="@+id/btnCallBack"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
<Button
android:text="Rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btnError"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="13dp"
android:id="@+id/btnRotate"
<Button
android:text="Scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnScale"
android:layout_alignLeft="@+id/btnCallBack"
android:layout_alignStart="@+id/btnCallBack"
android:layout_alignBottom="@+id/btnTarget"
<Button
android:text="Targets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnTarget"
android:layout_alignBaseline="@+id/btnRotate"
android:layout_alignBottom="@+id/btnRotate"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
</RelativeLayout>
MainActivity.java的代码如下:
package com.theitroad.picassotutorial;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ImageView imageView;
int i = 0;
Button btnDrawableImage, btnUrlImage, btnErrorImage, btnPlaceholderImage, btnCallback, btnResizeImage, btnRotateImage, btnScaleImage, btnTarget;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
imageView = (ImageView) findViewById(R.id.imageView);
btnDrawableImage = (Button) findViewById(R.id.btnDrawable);
btnUrlImage = (Button) findViewById(R.id.btnUrl);
btnPlaceholderImage = (Button) findViewById(R.id.btnPlaceholder);
btnErrorImage = (Button) findViewById(R.id.btnError);
btnCallback = (Button) findViewById(R.id.btnCallBack);
btnResizeImage = (Button) findViewById(R.id.btnResize);
btnRotateImage = (Button) findViewById(R.id.btnRotate);
btnScaleImage = (Button) findViewById(R.id.btnScale);
btnTarget = (Button) findViewById(R.id.btnTarget);
btnDrawableImage.setOnClickListener(this);
btnPlaceholderImage.setOnClickListener(this);
btnUrlImage.setOnClickListener(this);
btnCallback.setOnClickListener(this);
btnResizeImage.setOnClickListener(this);
btnErrorImage.setOnClickListener(this);
btnRotateImage.setOnClickListener(this);
btnScaleImage.setOnClickListener(this);
btnTarget.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnDrawable:
Picasso.with(this).load(R.drawable.image).into(imageView);
break;
case R.id.btnPlaceholder:
Picasso.with(this).load("www.theitroad.local").placeholder(R.drawable.placeholder).into(imageView);
break;
case R.id.btnUrl:
Picasso.with(this).load("https://cdn.theitroad.local/wp-content/uploads/2016/01/android-constraint-layout-sdk-tool-install.png").placeholder(R.drawable.placeholder).into(imageView);
break;
case R.id.btnError:
Picasso.with(this).load("www.theitroad.local").placeholder(R.drawable.placeholder).error(R.drawable.error).into(imageView);
break;
case R.id.btnCallBack:
Picasso.with(this).load("www.theitroad.local").error(R.mipmap.ic_launcher).into(imageView, new Callback() {
@Override
public void onSuccess() {
Log.d("TAG", "onSuccess");
}
@Override
public void onError() {
Toast.makeText(getApplicationContext(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.btnResize:
Picasso.with(this).load(R.drawable.image).resize(200, 200).into(imageView);
break;
case R.id.btnRotate:
Picasso.with(this).load(R.drawable.image).rotate(90f).into(imageView);
break;
case R.id.btnScale:
if (i == 3)
i = 0;
else {
if (i == 0) {
Picasso.with(this).load(R.drawable.image).fit().into(imageView);
Toast.makeText(getApplicationContext(), "Fit", Toast.LENGTH_SHORT).show();
} else if (i == 1) {
Picasso.with(this).load(R.drawable.image).resize(200, 200).centerCrop().into(imageView);
Toast.makeText(getApplicationContext(), "Center Crop", Toast.LENGTH_SHORT).show();
} else if (i == 2) {
Picasso.with(this).load(R.drawable.image).resize(200, 200).centerInside().into(imageView);
Toast.makeText(getApplicationContext(), "Center Inside", Toast.LENGTH_SHORT).show();
}
i++;
}
break;
case R.id.btnTarget:
Picasso.with(this).load("https://cdn.theitroad.local/wp-content/uploads/2016/01/android-constraint-layout-sdk-tool-install.png").placeholder(R.drawable.placeholder).error(R.drawable.error).into(target);
break;
}
}
private Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
imageView.setImageBitmap(bitmap);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
imageView.setImageDrawable(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
imageView.setImageDrawable(placeHolderDrawable);
}
};
}
本质上,在上面的代码中,我们在每次点击按钮时都实现了毕加索的功能。
- Drawable:单击此按钮可调用Picasso的最基本功能,即将可绘制图像加载到ImageView中
- 占位符:占位符通常用于在将主图像加载到imageview时显示可绘制图像。
在图像需要花费时间从Web加载的情况下,这是必不可少的。
.placeholder()仅在load方法之后才相关。
在上一行中,由于URl不会提取任何图像,因此ImageView会保留在占位符中。
网址:要从URl加载图片,网址应以字符串形式包含在
load()方法内错误:如果图像加载失败,通常会使用错误绘制对象。
在这种情况下,临时占位符图像将替换为放置在.error()方法内的错误可绘制对象。回调:毕加索提供了回调方法,通过这些方法,我们可以检查加载的图像的状态(成功/错误)并相应地显示文本。
发生错误时,我们也会显示相同的Toast消息,如下所示。调整大小:毕加索允许我们通过调用
resize()方法并传递所需的宽度和高度(以像素为单位),在将图像显示在ImageView中之前使用调整大小的图像Rotate:要旋转图像,请在
rotate()方法内部传递float值。
图片在其锚点(0,0)上以度为单位旋转缩放:调整图像大小可能会导致图像拉伸。
为了保持长宽比完整,请将centerCrop()或者centerInside()与resize()方法一起使用。
fit()就像延迟的resize()一样,它将图像缩小以适合ImageView的边界。
注意:fit不能与resize()一起使用,因为它具有内置的resize。
如果没有调用宽度和高度为正的resize(),则无法使用centerCrop和centerInside
- 目标:这是另一种回调形式,用作图像加载的侦听器。
目标是一个接口,它将返回位图图像及其占位符和错误drawable(如果已定义)。
我们可以进一步自定义方法onBitmapLoaded()返回的位图图像,或者直接在ImageView中显示它。
运行中的我们的android picasso示例应用程序的输出如下所示。
Android Picasso – .noFade()和.noPlaceholder()
默认情况下,毕加索会在imageview内部的图像中淡入淡出,以提供有意义的动画。
要删除此android动画,请在代码中调用方法noFade():
Picasso.with(this).load("www.theitroad.local").placeholder(R.drawable.placeholder).into(imageView);
当ImageView处理多个毕加索调用时,noPlaceholder()方法很方便。
采用常规方式(没有noPlaceholder方法)将导致每个新的Picasso调用将先前的图像更改为占位符,然后更改为新图像。
这看起来很难看,这就是noPlaceholder()帮助我们解决问题的地方。
Android Picasso –恢复/暂停/取消请求
要执行上述任何操作,我们首先需要将标记设置为:
Picasso.with(this).load("www.theitroad.local").error(R.mipmap.ic_launcher).into(imageView, new Callback() {
@Override
public void onSuccess() {
Log.d("TAG", "onSuccess");
}
@Override
public void onError() {
Toast.makeText(getApplicationContext(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
恢复,暂停或者取消请求通常是在ListView/RecyclerView中完成的。
Picasso.with(this).load().placeholder(R.drawable.placeholder).error(R.drawable.error).noFade().into(imageView);
Android Picasso优先请求
诸如下面的请求之类的请求更有可能在具有多个请求的ListView中首先完成。
Picasso.with(this).load().tag("Me").into(imageView);
priority()提供三种类型的常量:HIGH,NORMAL和LOW
注意:设置优先级只会给出请求调用的预期顺序。
不能严格遵守该命令。

