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
注意:设置优先级只会给出请求调用的预期顺序。
不能严格遵守该命令。