Android Picasso教程

时间:2020-02-23 14:29:09  来源:igfitidea点击:

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

注意:设置优先级只会给出请求调用的预期顺序。
不能严格遵守该命令。