Android Picasso is a powerful image downloading and caching library. In this tutorial, we’ll be discussing and implementing Picasso library in our android application.
Android Picasso是一个功能强大的图像下载和缓存库。 在本教程中,我们将在android应用程序中讨论和实现Picasso库 。
Android Picasso is an image loading/processing library developed and maintained by Square Inc. It’s immensely popular since it often requires just one line of code and has a similar style of coding for each of its features(we’ll be implementing them soon!). To use the android Picasso Library in your Android Studio project, add the following dependency in your build.gradle
file.
Android Picasso是由Square Inc开发和维护的图像加载/处理库。它非常受欢迎,因为它通常只需要一行代码,并且每个功能都有类似的编码风格(我们将尽快实现!) 。 要在Android Studio项目中使用android Picasso Library,请在build.gradle
文件中添加以下依赖build.gradle
。
compile 'com.squareup.picasso:picasso:2.5.2'
Android Picasso comes with its own set of features such as:
Android Picasso带有自己的一组功能,例如:
To load a image from URL in an ImageView using picasso api, following code snippet is commonly used.
要使用picasso api从ImageView中的 URL加载图像,通常使用以下代码段。
Picasso.with(context).load("https://cdn.journaldev.com/wp-content/uploads/2016/11/android-image-picker-project-structure.png").into(imageView)
To load a resource (drawable/mipmap):
加载资源 (可绘制/ mipmap):
Picasso.with(context).load(R.mipmap.ic_launcher).into(imageView);
To load a file image :
加载文件图像 :
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Sample.jpg");
Picasso.with(context).load(file).into(imageView);
Picasso by default tries to get an image from the memory first. To prevent this we can add the method noMemoryPolicy()
by calling either or both of the enums MemoryPolicy.NO_CAHE, MemoryPolicy.NO_STORE.
默认情况下,毕加索会尝试先从内存中获取图像。 为了防止这种情况,我们可以通过调用枚举 MemoryPolicy.NO_CAHE , MemoryPolicy.NO_STORE中的一个或两个来添加方法noMemoryPolicy()
。
Picasso.with(context).load(image_url).memoryPolicy(MemoryPolicy.NO_CACHE).into(imageView);
Picasso.with(context).load(image_url).memoryPolicy(MemoryPolicy.NO_STORE).into(imageView);
If the image is not served/prevented from the Memory, Picasso next tries to get it from the Disk Cache.
To skip the disk cache we need to call the method .networkPolicy() with the parameter set as NetworkPolicy.NO_CACHE
如果未从内存中提供/阻止该图像,则毕加索接下来将尝试从磁盘缓存中获取该图像。
要跳过磁盘缓存,我们需要使用参数设置为NetworkPolicy.NO_CACHE来调用.networkPolicy()方法。
Another useful enum is NetworkPolicy.OFFLINE which would check for the image in the cache only. It’ll show the error image(if defined) or blank if the image is not found in the cache.
另一个有用的枚举是NetworkPolicy.OFFLINE ,它将仅检查缓存中的图像。 它会显示错误图像(如果已定义);如果在缓存中找不到该图像,则会显示空白。
Picasso.with(context).load(image_url).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
Let’s dive into the coding part of android picasso tutorial where we’ll see and implement all the features together.
让我们深入研究android picasso教程的编码部分,在此我们将一起看到并实现所有功能。
The activity_main.xml
is given below.
下面给出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.journaldev.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>
The code for MainActivity.java
is given below:
MainActivity.java
的代码如下:
package com.journaldev.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.journaldev.com").placeholder(R.drawable.placeholder).into(imageView);
break;
case R.id.btnUrl:
Picasso.with(this).load("https://cdn.journaldev.com/wp-content/uploads/2017/01/android-constraint-layout-sdk-tool-install.png").placeholder(R.drawable.placeholder).into(imageView);
break;
case R.id.btnError:
Picasso.with(this).load("www.journaldev.com").placeholder(R.drawable.placeholder).error(R.drawable.error).into(imageView);
break;
case R.id.btnCallBack:
Picasso.with(this).load("www.journaldev.com").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.journaldev.com/wp-content/uploads/2017/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);
}
};
}
Essentially in the above code, we’ve implemented a feature of Picasso on each button click.
基本上在上面的代码中,我们在每次单击按钮时都实现了毕加索的功能。
Picasso.with(this).load("www.journaldev.com").placeholder(R.drawable.placeholder).into(imageView);
A .placeholder()
is relevant only after the load
method. In the above line, since the URl doesn’t fetch any image, the ImageView stays with the placeholder.
.placeholder()
仅在load
方法之后才相关。 在上面的代码行中,由于URl不会获取任何图像,因此ImageView将保留在占位符中。
load()
method URL :要从URl加载图像,URL被作为字符串括在load()
方法内 .error()
method. 错误 :在加载图像失败的情况下,通常使用一个可绘制的错误。 在这种情况下,临时占位符图像将替换为放置在.error()
方法内的错误可绘制对象。 Picasso.with(this).load("www.journaldev.com").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();
}
});
回调 :毕加索提供了回调方法,通过这些方法,我们可以检查加载的图像的状态(成功/错误)并相应地显示文本。 发生错误时,我们已经显示了相同的Toast消息,如下所示。 resize()
and passing the desired width and height in pixels 调整大小 :毕加索允许我们通过调用resize()
方法并以像素为单位传递所需的宽度和高度,从而在将图像显示在ImageView中之前使用调整图像的resize()
rotate()
method. The image is rotated in degrees upon it’s anchor point (0,0) Rotate :要旋转图像,请在rotate()
方法内部传递float值。 图像在其锚点(0,0)上以度为单位旋转 centerCrop()
or centerInside()
with the resize()
method.fit()
is like a delayed resize(), that reduces the image to fit the ImageView bounds.resize()
with a positive width and height 缩放 :调整图像大小会导致图像拉伸。 要保持长宽比不变,请使用带有resize()
方法的centerCrop()
或centerInside()
。 fit()
就像延迟的resize()一样,它将图像缩小以适合ImageView边界。 resize()
,则不能使用centerCrop和centerInside onBitmapLoaded()
or directly show it in the ImageView Targets :这是回调的另一种形式,用作图像加载的侦听器。 目标是一个接口,它将返回位图图像及其占位符和错误drawable(如果已定义)。 我们可以进一步自定义方法onBitmapLoaded()
返回的位图图像,或直接在ImageView中显示它。 The output of the our android picasso example application in action is shown below.
运行中的我们的android picasso示例应用程序的输出如下所示。
Picasso by default fades in the image inside the imageview to provide a meaningful animation. To remove this android animation invoke the method noFade()
in the code as :
默认情况下,毕加索会在imageview内部的图像中淡入淡出,以提供有意义的动画。 要删除此android动画 ,请在代码中调用noFade()
方法:
Picasso.with(this).load().placeholder(R.drawable.placeholder).error(R.drawable.error).noFade().into(imageView);
A noPlaceholder()
method is handy when an ImageView handles multiple Picasso calls. Going the conventional way(without noPlaceholder method) would cause every new Picasso call to change the previous image to the placeholder and then to the new image. This can look ugly and this is where noPlaceholder()
comes to our rescue.
当ImageView处理多个Picasso调用时, noPlaceholder()
方法很方便。 采用常规方式(没有noPlaceholder方法)将导致每个新的Picasso调用将先前的图像更改为占位符,然后更改为新图像。 这看起来很难看,这就是noPlaceholder()
拯救我们的地方。
To do any of the above, we need to first set a tag as :
要执行上述任何一项操作,我们首先需要将标记设置为:
Picasso.with(this).load().tag("Me").into(imageView);
Resuming, Pausing or Cancelling a request is generally done in ListView/RecyclerView.
恢复,暂停或取消请求通常是在ListView / RecyclerView中完成的 。
Picasso.with(this).resumeTag("Me");
Picasso.with(this).pauseTag("Me");
Picasso.with(this).cancelTag("Me");
Picasso.with(this).cancelRequest(imageView); //alternative
A request such as the one below has higher chances of getting completed first in a ListView which many multiple requests.
诸如下面的请求之类的请求更有可能在具有多个请求的ListView中首先完成。
Picasso.with(this).load().priority(HIGH).into(imageView);
priority()
offers three types of Constants : HIGH, NORMAL and LOW
priority()
提供三种类型的常量: HIGH , NORMAL和LOW
Note: Setting a priority just gives an intended order of request calls. It doesn’t gurantee to strictly follow the order.
注意 :设置优先级只会给出请求调用的预期顺序。 严格遵守该命令并不保证。
This brings an end to android picasso tutorial. You can download the final Android Picasso example project from the link given below.
这就结束了android picasso教程。 您可以从下面提供的链接下载最终的Android Picasso示例项目。
翻译自: https://www.journaldev.com/13759/android-picasso-tutorial