Android中圖片載入框架Picasso的使用
阿新 • • 發佈:2019-01-28
技術要點
- 基本顯示(非同步載入,圖片壓縮,圖片快取)
- 載入中和載入錯誤的圖片顯示
- 設定圖片尺寸(Resize)、縮放(Scale)和裁剪(Crop)
- 圖片旋轉
- 設定轉換器
- 取消預設的記憶體快取
- 設定快取指示器
- 請求優先順序設定
- 圖片還未加載出來時取消Picasso的請求
- 其它擴充套件功能
Demo展示圖片
佈局程式碼
//(layout)activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.test.picassodemo.activity.MainActivity">
<ImageView
android:id="@+id/imageView1"
android:layout_weight ="1"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="0dp"/>
<ImageView
android:id="@+id/imageView2"
android:layout_weight="1"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height ="0dp"/>
</LinearLayout>
----------------------------------------------------------------------------------------
//(menu)main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/fromInternet"
android:showAsAction="never"
android:title="fromInternet"/>
<item
android:id="@+id/fromUri"
android:showAsAction="never"
android:title="fromUri"/>
<item
android:id="@+id/fromFile"
android:showAsAction="never"
android:title="fromFile"/>
<item
android:id="@+id/fromResourse"
android:showAsAction="never"
android:title="fromResourse"/>
<item
android:id="@+id/noFade"
android:showAsAction="never"
android:title="noFade"/>
<item
android:id="@+id/reSize"
android:showAsAction="never"
android:title="reSize"/>
<item
android:id="@+id/transformation1"
android:showAsAction="never"
android:title="transformation1"/>
<item
android:id="@+id/transformation2"
android:showAsAction="never"
android:title="transformation2"/>
<item
android:id="@+id/transformation3"
android:showAsAction="never"
android:title="transformation3"/>
<item
android:id="@+id/transformation4"
android:showAsAction="never"
android:title="transformation4"/>
<item
android:id="@+id/cache"
android:showAsAction="never"
android:title="cache"/>
<item
android:id="@+id/indicator"
android:showAsAction="never"
android:title="indicator"/>
</menu>
----------------------------------------------------------------------------------------
//(values)dimens
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="image_width">200dp</dimen>
<dimen name="image_height">200dp</dimen>
----------------------------------------------------------------------------------------
activity程式碼
注:不要忘了設定網路許可權
<uses-permission android:name="android.permission.INTERNET"/>
新增Gradle依賴
compile 'com.squareup.picasso:picasso:2.5.2'
//(activity)MainActivity
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import com.squareup.picasso.MemoryPolicy;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import com.test.picassodemo.R;
import com.test.picassodemo.transformation.BlurTransformation;
import com.test.picassodemo.transformation.CircleImageTransformation;
import com.test.picassodemo.transformation.CropSquareTransformation;
import com.test.picassodemo.transformation.GrayTransformation;
import com.test.picassodemo.transformation.RoundTransformation;
public class MainActivity extends AppCompatActivity {
private Context mContext = MainActivity.this;
private ImageView mImageView1;
private ImageView mImageView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
mImageView1 = (ImageView) findViewById(R.id.imageView1);
mImageView2 = (ImageView) findViewById(R.id.imageView2);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.fromInternet:
// fromInterNet 預設是非同步載入
// placeholder和error通常在網路載入中使用
// placeholder提供一張在網路請求還沒有完成時顯示的圖片,它必須是本地圖片
// error提供一張在載入圖片出錯的情況下顯示的預設圖片,它必須是本地圖片
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/52/d/102.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
// 設定請求的優先順序 高,預設是正常
.priority(Picasso.Priority.HIGH)
// 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
.tag("photoTag")
.into(mImageView1);
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/52/d/105.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
// 設定請求的優先順序 低,預設是正常
.priority(Picasso.Priority.LOW)
// 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
.tag("photoTag")
.into(mImageView2);
break;
case R.id.noFade:
// fromInterNet 預設是非同步載入
// noFade 取消漸入過度效果
Picasso.with(mContext)
.load("http://img2.3lian.com/2014/c7/12/d/77.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.noFade()
.tag("photoTag")
.into(mImageView1);
Picasso.with(mContext)
.load("http://img2.3lian.com/2014/c7/12/d/82.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.noFade()
.tag("photoTag")
.into(mImageView2);
break;
case R.id.reSize:
// fromInterNet 預設是非同步載入
// reSize 設定圖片尺寸
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/110/d/13.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
// 使用dp設定圖片寬高
.resizeDimen(R.dimen.image_width,R.dimen.image_height)
// 使用px設定圖片寬高
// .resizeDimen(400,200)
// 只有當原始圖片的尺寸大於我們指定的尺寸時,resize才起作用
.onlyScaleDown()
// 以(pivotX, pivotY)為原點旋轉
.rotate(180,200,100)
.tag("photoTag")
.into(mImageView1);
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/110/d/11.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
// 使用dp設定圖片寬高
.resizeDimen(R.dimen.image_width,R.dimen.image_height)
// 使用px設定圖片寬高
// .resizeDimen(400,200)
// 只有當原始圖片的尺寸大於我們指定的尺寸時,resize才起作用
.onlyScaleDown()
// 以(pivotX, pivotY)為原點旋轉
.rotate(180,200,100)
.tag("photoTag")
.into(mImageView2);
break;
case R.id.fromUri:
// fromUri
break;
case R.id.fromFile:
// fromFile
break;
case R.id.fromResourse:
// fromResourse
Picasso.with(mContext).load(R.mipmap.pic1).into(mImageView1);
Picasso.with(mContext).load(R.mipmap.pic2).into(mImageView2);
break;
case R.id.transformation1:
// 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
// 高斯模糊
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/110/d/12.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new BlurTransformation(mContext))
.tag("photoTag")
.into(mImageView1);
// 度灰處理
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/110/d/15.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new GrayTransformation())
.tag("photoTag")
.into(mImageView2);
break;
case R.id.transformation2:
// 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
// 圓角處理
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/120/d/120.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new RoundTransformation(30))
.tag("photoTag")
.into(mImageView1);
// 圓形遮罩處理
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a1/120/d/122.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new CircleImageTransformation())
.tag("photoTag")
.into(mImageView2);
break;
case R.id.transformation3:
// 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
// 方形圖片
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a2/58/d/146.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new CropSquareTransformation())
.tag("photoTag")
.into(mImageView1);
break;
case R.id.transformation4:
// 對圖片進行高斯模糊、新增圓角、度灰、圓形圖片等處理
// 混合處理(新增圓角、度灰處理)
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a2/58/d/146.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
// 有些還是不能一起使用 比如圓角和灰度一起使用沒效果
// 灰度和圓形遮罩一起使用 顯示外圍邊框線
// .transform(new GrayTransformation())
.transform(new RoundTransformation(100))
.transform(new BlurTransformation(mContext))
.tag("photoTag")
.into(mImageView1);
// 混合處理(新增高斯模糊、圓形遮罩處理)
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/a2/58/d/151.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.transform(new BlurTransformation(mContext))
.transform(new CircleImageTransformation())
.tag("photoTag")
.into(mImageView2);
break;
case R.id.cache:
// 預設記憶體快取和磁碟快取都開啟,圖片保存於記憶體中容易OOM,取消記憶體快取
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/53/d/8.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
// 設定請求的優先順序 高,預設是正常
.priority(Picasso.Priority.HIGH)
// 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
//跳過記憶體快取
.memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)
//跳過磁碟快取
.networkPolicy(NetworkPolicy.NO_CACHE)
.tag("photoTag")
.into(mImageView1);
// 預設記憶體快取和磁碟快取都開啟,圖片保存於記憶體中容易OOM,取消記憶體快取
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/53/d/5.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
// 設定請求的優先順序 高,預設是正常
.priority(Picasso.Priority.HIGH)
// 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
//強制從快取獲取結果
.networkPolicy(NetworkPolicy.OFFLINE)
.tag("photoTag")
.into(mImageView2);
break;
case R.id.indicator:
// 開啟快取指示器 true為開啟
// 紅色表示網路載入 藍色表示磁碟載入 綠色表示快取載入
Picasso.with(mContext).setIndicatorsEnabled(true);
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/53/d/2.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.tag("photoTag")
.into(mImageView1);
Picasso.with(mContext)
.load("http://img1.3lian.com/2015/w2/53/d/6.jpg")
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.centerCrop()
.fit()
.tag("photoTag")
.into(mImageView2);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
// 設定Tag,可以在退出介面,圖片還未加載出來時取消Picasso的請求
Picasso.with(mContext).cancelTag("PhotoTag");
super.onDestroy();
}
}
transformation程式碼
//(transformation)BlurTransformation
import android.content.Context;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import com.squareup.picasso.Transformation;
/**
* 高斯模糊處理
*/
public 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";
}
}
----------------------------------------------------------------------------------------
//(transformation)CircleImageTransformation
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import com.squareup.picasso.Transformation;
/**
* 圓形遮罩處理
*/
public class CircleImageTransformation implements Transformation{
@Override
public Bitmap transform(Bitmap source) {
int minEdge = Math.min(source.getWidth(), source.getHeight());
int dx = (source.getWidth() - minEdge) / 2;
int dy = (source.getHeight() - minEdge) / 2;
// Init shader
Shader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Matrix matrix = new Matrix();
matrix.setTranslate(-dx, -dy); // Move the target area to center of the source bitmap
shader.setLocalMatrix(matrix);
// Init paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShader(shader);
// Create and draw circle bitmap
Bitmap output = Bitmap.createBitmap(minEdge, minEdge, source.getConfig());
Canvas canvas = new Canvas(output);
canvas.drawOval(new RectF(0, 0, minEdge, minEdge), paint);
// Recycle the source bitmap, because we already generate a new one
source.recycle();
return output;
}
@Override
public String key() {
return "circleImage";
}
}
----------------------------------------------------------------------------------------
//(transformation)CropSquareTransformation
import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;
/**
* 正方形切割
*/
public class CropSquareTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap result = Bitmap.createBitmap(source, x, y, size, size);
if (result != source) {
source.recycle();
}
return result;
}
@Override
public String key() {
return "square";
}
}
----------------------------------------------------------------------------------------
//(transformation)GrayTransformation
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
/**
* 灰度處理
*/
public 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";
}
}
----------------------------------------------------------------------------------------
//(transformation)RoundTransformation
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import com.squareup.picasso.Transformation;
/**
* 圓角處理
*/
public class RoundTransformation implements Transformation {
private int radius;//圓角值
public RoundTransformation(int radius) {
this.radius = radius;
}
@Override
public Bitmap transform(Bitmap source) {
int width = source.getWidth();
int height = source.getHeight();
//畫板
Bitmap bitmap = Bitmap.createBitmap(width, height, source.getConfig());
Paint paint = new Paint();
Canvas canvas = new Canvas(bitmap);//建立同尺寸的畫布
paint.setAntiAlias(true);//畫筆抗鋸齒
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
//畫圓角背景
RectF rectF = new RectF(new Rect(0, 0, width, height));//賦值
canvas.drawRoundRect(rectF, radius, radius, paint);//畫圓角矩形
//
paint.setFilterBitmap(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(source, 0, 0, paint);
source.recycle();//釋放
return bitmap;
}
@Override
public String key() {
return "round";
}
}