图片处理自带缓存的Picasso

搞Android的都知道对图片的下载和缓存处理非常的麻烦至极,动不动就发生OOM之类的情况。特别是在Listview,GridView,ViewPage等控件里面。至此介绍Picasso图片缓存框架使用。相对ImageLoad等框架更为方便快速开发者使用。介绍下Picasso;

PicassoSquare公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能。仅仅只需要一行代码就能完全实现图片的异步加载。

[java]  view plain  copy
  1. Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);  


Picasso不仅实现了图片异步加载的功能,还解决了android中加载图片时需要解决的一些常见问题:

1.adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题

2.使用复杂的图片压缩转换来尽可能的减少内存消耗

3.自带内存和硬盘二级缓存功能。

以前在做程序的时候,加载网络图片一般都使用volley来处理,虽然这个第三方插件很好用,可是它有一个问题,就是无法加载本地图片。最近群里有一个兄弟,提到了picasso。所以也就试了一下,感觉不错,现在把其中的一些方法记录下来。

       官方地址:http://square.github.io/picasso/

       下载地址:https://github.com/square/picasso    

        我使用的是android studio进行开发,所以比较简单,只要引用compile 'com.squareup.picasso:picasso:2.5.2'即可,你可以去下载地址里,找最新版本。

        我们先来简单看一下效果图:

        

      网有点卡,所以在第一个页面中,没有体现出,等待的效果,等待的图片就是哪个圆的小笑脸。因为等图片显示出来,这个GIF就太大了。大家看一下意思就行了。下面我们来看一下代码:

      第一步,先在app/build.gradle文件添加插件的依赖

    

[html]  view plain  copy
 
  1. dependencies {  
  2.       compile fileTree(dir: 'libs', include: ['*.jar'])  
  3.       compile 'com.android.support:appcompat-v7:23.1.1'  
  4.       compile 'com.squareup.picasso:picasso:2.5.2'       //这个就是  
  5. }  

     好,下面我来看一下代码,代码相对简单,就两个页面,一个是在普通的 activity 中显示网络图片,第二个是就是在listView中显示网络图片。好了,不多说,我们直接看代码。

    activity_main.xml主页面布局,没什么特别的,就是一个按钮,为了跳转到ListView页面用,另外加了几个ImageView,每个都是一个不同的picasso的使用

   

[html]  view plain  copy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context=".MainActivity"  
  6.     android:orientation="vertical">  
  7.     <ScrollView  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent">  
  10.         <LinearLayout  
  11.             android:layout_width="match_parent"  
  12.             android:layout_height="wrap_content"  
  13.             android:orientation="vertical">  
  14.             <Button  
  15.                 android:id="@+id/btn_listView"  
  16.                 android:layout_width="match_parent"  
  17.                 android:layout_height="wrap_content"  
  18.                 android:gravity="center"  
  19.                 android:text="ListView显示图片"/>  
  20.             <TextView  
  21.                 android:layout_width="match_parent"  
  22.                 android:layout_height="wrap_content"  
  23.                 android:text="下图是根据ImageView大小,显示图片"/>  
  24.             <ImageView  
  25.                 android:id="@+id/img_one"  
  26.                 android:layout_width="150dp"  
  27.                 android:layout_height="200dp" />  
  28.             <TextView  
  29.                 android:layout_width="match_parent"  
  30.                 android:layout_height="wrap_content"  
  31.                 android:text="下图是通过程序代码,来显示图片大小"/>  
  32.             <ImageView  
  33.                 android:id="@+id/img_two"  
  34.                 android:layout_width="150dp"  
  35.                 android:layout_height="100dp" />  
  36.             <TextView  
  37.             android:layout_width="match_parent"  
  38.             android:layout_height="wrap_content"  
  39.             android:text="加载本地的图片"/>  
  40.             <ImageView  
  41.                 android:id="@+id/img_three"  
  42.                 android:layout_width="50dp"  
  43.                 android:layout_height="50dp" />  
  44.             <TextView  
  45.                 android:layout_width="match_parent"  
  46.                 android:layout_height="wrap_content"  
  47.                 android:text="截取图片"/>  
  48.             <ImageView  
  49.                 android:id="@+id/img_four"  
  50.                 android:layout_width="150dp"  
  51.                 android:layout_height="150dp" />  
  52.         LinearLayout>  
  53.     ScrollView>  
  54.   
  55. LinearLayout>  

     MainActivity.java主页程序,不多说了,里面的注解感觉写得还是比较细的。大家看一下吧

    

[java]  view plain  copy
 
  1. package com.example.cg.picassolearn;  
  2.   
  3. import android.os.Bundle;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.view.View;  
  6. import android.widget.Button;  
  7. import android.widget.ImageView;  
  8.   
  9. import com.example.cg.picassolearn.untils.CropSquareTransformation;  
  10. import com.squareup.picasso.Picasso;  
  11.   
  12. public class MainActivity extends AppCompatActivity implements View.OnClickListener {  
  13.   
  14.     private ImageView img_one;  
  15.     private ImageView img_two;  
  16.     private ImageView img_three;  
  17.     private ImageView img_four;  
  18.   
  19.     private Button btn_listView;  
  20.   
  21.     @Override  
  22.     protected void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_main);  
  25.   
  26.         initControls();  
  27.   
  28.         initData();  
  29.     }  
  30.   
  31.     /** 
  32.      * 初始化控件 
  33.      */  
  34.     private void initControls() {  
  35.   
  36.         img_one = (ImageView)this.findViewById(R.id.img_one);  
  37.         img_two = (ImageView)this.findViewById(R.id.img_two);  
  38.         img_three = (ImageView)this.findViewById(R.id.img_three);  
  39.         img_four = (ImageView)this.findViewById(R.id.img_four);  
  40.         btn_listView = (Button)findViewById(R.id.btn_listView);  
  41.         btn_listView.setOnClickListener(this);  
  42.     }  
  43.   
  44.     /** 
  45.      * 加载数据 
  46.      */  
  47.     private void initData()  
  48.     {  
  49.         /** 
  50.          * 根据ImageView大小,显示图片 
  51.          * .fit()                                  说明:控件不能设置成wrap_content,也就是必须有大小才行,fit()才让图片的宽高等于控件的宽高,设置fit(),不能再调用resize() 
  52.          * .placeholder(R.drawable.topic_tom)      说明:当图片没有加载上的时候,显示的图片 
  53.          * .error(R.drawable.topic_sky)            说明:当图片加载错误的时候,显示图片 
  54.          * .into(img_one)                          说明:将图片加载到哪个控件中 
  55.          */  
  56.         Picasso.with(this).load("http://g.hiphotos.baidu.com/image/pic/item/c9fcc3cec3fdfc03e426845ed03f8794a5c226fd.jpg")  
  57.                 .fit()  
  58.                 .placeholder(R.drawable.topic_tom)  
  59.                 .error(R.drawable.topic_sky)  
  60.                 .into(img_one);  
  61.         /** 
  62.          * 通过程序代码,来显示图片大小 
  63.          *.resize(200, 150)                        说明:为图片重新定义大小 
  64.          *.centerCrop()                            说明:图片要填充整个控件,去两边留中间 
  65.          */  
  66.         Picasso.with(this).load("http://d.hiphotos.baidu.com/image/h%3D200/sign=745574b6a2ec08fa390014a769ee3d4d/cb8065380cd79123148b447daf345982b2b78054.jpg")  
  67.                 .resize(200150)  
  68.                 .centerCrop()  
  69.                 .placeholder(R.drawable.topic_tom)  
  70.                 .error(R.drawable.topic_sky)  
  71.                 .into(img_two);  
  72.   
  73.         /** 
  74.          * 加载本地数据库,图片的大小,取消于控件设置的大小 
  75.          */  
  76.         Picasso.with(this).load(R.drawable.topic_tom)  
  77.                 .into(img_three);  
  78.   
  79.   
  80.         /** 
  81.          * 截取图片 
  82.          * .transform(new CropSquareTransformation())        说明:通过程序截取图片 
  83.          */  
  84.         Picasso.with(this).load("http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg")  
  85.                 .transform(new CropSquareTransformation())  
  86.                 .placeholder(R.drawable.topic_tom)  
  87.                 .error(R.drawable.topic_sky)  
  88.                 .into(img_four);  
  89.     }  
  90.   
  91.   
  92.     @Override  
  93.     public void onClick(View v) {  
  94.         switch (v.getId())  
  95.         {  
  96.             case R.id.btn_listView:  
  97.                 ListViewActivity.ListViewStar(this);  
  98.                 break;  
  99.         }  
  100.     }  
  101. }  

    这里在, 在截取图片的地方,需要自己编写代码,当然了,你只要实现picasso中的transform就行,我们来看一下代码:

    CropSquareTransformation.java

   

[java]  view plain  copy
 
  1. package com.example.cg.picassolearn.untils;  
  2.   
  3. import android.graphics.Bitmap;  
  4.   
  5. import com.squareup.picasso.Transformation;  
  6.   
  7. /** 
  8.  * picasso的Transformation方法,对图片进行截取 
  9.  * Created by cg on 2016/2/1. 
  10.  */  
  11. public class CropSquareTransformation implements Transformation {  
  12.   
  13.     //截取从宽度和高度最小作为bitmap的宽度和高度  
  14.     @Override  
  15.     public Bitmap transform(Bitmap source) {  
  16.         int size=Math.min(source.getWidth(),source.getHeight());  
  17.         int x=(source.getWidth()-size)/2;  
  18.         int y=(source.getHeight()-size)/2;  
  19.         Bitmap result=Bitmap.createBitmap(source,x,y,size,size);  
  20.         if (result!=source){  
  21.             source.recycle();//释放bitmap  
  22.         }  
  23.         return result;  
  24.     }  
  25.   
  26.     @Override  
  27.     public String key() {  
  28.         return "square()";  
  29.     }  
  30. }  

    看到上面的用法,是不是感觉picasso很好用,而且使用也很简单,就是一行代码,就搞定了。无论是本地图片还是网络图片,当然了,在这里,你不用担心什么OOM,二级缓存等问题,因为它本身都已经解决了这些问题。

    在程序中最常用到图片显示可能就是ListView中的应用了,下面我们来看一下,它在listView中的使用。也是相应简单,同样的一行代码。

    首先,我们要先建立一个bean,里面放一个图片地址,标题,内容。为了给listVIew加值

    News.java

   

[java]  view plain  copy
 
  1. package com.example.cg.picassolearn.bean;  
  2.   
  3. /** 
  4.  * Created by cg on 2016/2/1. 
  5.  */  
  6. public class News {  
  7.   
  8.     private String title;  
  9.     private String contents;  
  10.     private String PicUrl;  
  11.   
  12.     public News() {  
  13.     }  
  14.   
  15.     public News(String title, String contents, String picUrl) {  
  16.         this.title = title;  
  17.         this.contents = contents;  
  18.         PicUrl = picUrl;  
  19.     }  
  20.   
  21.     public String getTitle() {  
  22.         return title;  
  23.     }  
  24.   
  25.     public void setTitle(String title) {  
  26.         this.title = title;  
  27.     }  
  28.   
  29.     public String getContents() {  
  30.         return contents;  
  31.     }  
  32.   
  33.     public void setContents(String contents) {  
  34.         this.contents = contents;  
  35.     }  
  36.   
  37.     public String getPicUrl() {  
  38.         return PicUrl;  
  39.     }  
  40.   
  41.     public void setPicUrl(String picUrl) {  
  42.         PicUrl = picUrl;  
  43.     }  
  44. }  

   下面我为ListView的Item添加布局

    lv_item.xml

   

[html]  view plain  copy
 
  1. xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal">  
  6.   
  7.     <LinearLayout  
  8.         android:layout_width="0dp"  
  9.         android:layout_height="110dp"  
  10.         android:layout_weight="1"  
  11.         android:gravity="center">  
  12.         <ImageView  
  13.             android:id="@+id/item_pic"  
  14.             android:layout_width="100dp"  
  15.             android:layout_height="100dp" />  
  16.     LinearLayout>  
  17.     <LinearLayout  
  18.         android:layout_width="0dp"  
  19.         android:layout_height="110dp"  
  20.         android:layout_weight="3"  
  21.         android:orientation="vertical">  
  22.         <TextView  
  23.             android:id="@+id/txt_title"  
  24.             android:layout_width="match_parent"  
  25.             android:layout_height="0dp"  
  26.             android:layout_weight="1"/>  
  27.         <TextView  
  28.             android:id="@+id/txt_content"  
  29.             android:layout_width="match_parent"  
  30.             android:layout_height="0dp"  
  31.             android:layout_weight="2"/>  
  32.     LinearLayout>  
  33.   
  34. LinearLayout>  

   为ListView编写一个Adapter,这些都是最基础的代码,我就不多说了

   lv_Adapter.java

  

[java]  view plain  copy
 
  1. package com.example.cg.picassolearn;  
  2.   
  3. import android.content.Context;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.BaseAdapter;  
  8. import android.widget.ImageView;  
  9. import android.widget.TextView;  
  10.   
  11. import com.example.cg.picassolearn.bean.News;  
  12. import com.squareup.picasso.Picasso;  
  13.   
  14. import java.util.List;  
  15.   
  16. /** 
  17.  * ListView的Adapter 
  18.  * Created by cg on 2016/2/1. 
  19.  */  
  20. public class lv_Adapter extends BaseAdapter{  
  21.   
  22.     private List list_new;  
  23.     private LayoutInflater inflater;  
  24.     private Context context;  
  25.   
  26.     public lv_Adapter(List list_new, Context context) {  
  27.         this.list_new = list_new;  
  28.         this.context = context;  
  29.         this.inflater = LayoutInflater.from(context);  
  30.     }  
  31.   
  32.     @Override  
  33.     public int getCount() {  
  34.         return list_new.size();  
  35.     }  
  36.   
  37.     @Override  
  38.     public Object getItem(int position) {  
  39.         return list_new.get(position);  
  40.     }  
  41.   
  42.     @Override  
  43.     public long getItemId(int position) {  
  44.         return position;  
  45.     }  
  46.   
  47.     @Override  
  48.     public View getView(int position, View convertView, ViewGroup parent) {  
  49.   
  50.         ItemNews in;  
  51.         if(convertView==null)  
  52.         {  
  53.             in = new ItemNews();  
  54.   
  55.             convertView = inflater.inflate(R.layout.lv_item,null);  
  56.             in.title = (TextView)convertView.findViewById(R.id.txt_title);  
  57.             in.contents = (TextView)convertView.findViewById(R.id.txt_content);  
  58.             in.pic = (ImageView)convertView.findViewById(R.id.item_pic);  
  59.   
  60.             convertView.setTag(in);  
  61.         }else  
  62.         {  
  63.             in = (ItemNews)convertView.getTag();  
  64.         }  
  65.   
  66.         in.contents.setText(list_new.get(position).getContents());  
  67.         in.title.setText(list_new.get(position).getTitle());  
  68.   
  69.         //注意这里,一行代码,就把图片加载上去了,而且你上下滚动listView你会发现什么,这个大家自己去体会  
  70.         Picasso.with(context).load(list_new.get(position).getPicUrl()).fit()  
  71.                 .placeholder(R.drawable.topic_tom)  
  72.                 .error(R.drawable.topic_sky)  
  73.                 .into(in.pic);  
  74.   
  75.         return convertView;  
  76.     }  
  77.   
  78.   
  79.     class ItemNews  
  80.     {  
  81.         TextView title;  
  82.         ImageView pic;  
  83.         TextView contents;  
  84.     }  
  85. }  
   好,ListView页面代码:

  ListViewActivity.java

 

[java]  view plain  copy
 
  1. package com.example.cg.picassolearn;  
  2.   
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.support.v7.app.AppCompatActivity;  
  7. import android.widget.ListView;  
  8.   
  9. import com.example.cg.picassolearn.bean.News;  
  10.   
  11. import java.util.ArrayList;  
  12. import java.util.List;  
  13.   
  14. public class ListViewActivity extends AppCompatActivity {  
  15.   
  16.     private ListView lv_main;  
  17.     private List list_new;  
  18.     private lv_Adapter lAdapter;  
  19.   
  20.     public static void ListViewStar(Context context)  
  21.     {  
  22.         Intent intent = new Intent(context,ListViewActivity.class);  
  23.         context.startActivity(intent);  
  24.     }  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_list_view);  
  30.           
  31.         initControls();  
  32.   
  33.         initData();  
  34.     }  
  35.   
  36.     /** 
  37.      * 初始化控件 
  38.      */  
  39.     private void initControls() {  
  40.         lv_main = (ListView)findViewById(R.id.lv_main);  
  41.         list_new = new ArrayList<>();  
  42.         lAdapter = new lv_Adapter(list_new,this);  
  43.         lv_main.setAdapter(lAdapter);  
  44.     }  
  45.   
  46.     /** 
  47.      * 初始化数据 
  48.      */  
  49.     private void initData()  
  50.     {  
  51.         News news = new News();  
  52.         news.setTitle("清纯的美女");  
  53.         news.setContents("我不说什么,大家自己看");  
  54.         news.setPicUrl("http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg");  
  55.         list_new.add(news);  
  56.   
  57.         News news2 = new News();  
  58.         news2.setTitle("好看的美女");  
  59.         news2.setContents("我不说什么,大家自己看");  
  60.         news2.setPicUrl("http://f.hiphotos.baidu.com/image/pic/item/11385343fbf2b211eee0554ac88065380dd78eec.jpg");  
  61.         list_new.add(news2);  
  62.   
  63.         News news1 = new News();  
  64.         news1.setTitle("狂野的美女");  
  65.         news1.setContents("我不说什么,大家自己看");  
  66.         news1.setPicUrl("http://a.hiphotos.baidu.com/image/h%3D200/sign=623f372f0b24ab18ff16e63705fbe69a/267f9e2f070828382f690e1dba99a9014c08f157.jpg");  
  67.         list_new.add(news1);  
  68.   
  69.         News news4 = new News();  
  70.         news4.setTitle("小护士");  
  71.         news4.setContents("我不说什么,大家自己看");  
  72.         news4.setPicUrl("http://f.hiphotos.baidu.com/image/pic/item/738b4710b912c8fc6684dceaf9039245d68821a5.jpg");  
  73.         list_new.add(news4);  
  74.   
  75.         News news5 = new News();  
  76.         news5.setTitle("古典的美女");  
  77.         news5.setContents("我不说什么,大家自己看");  
  78.         news5.setPicUrl("http://c.hiphotos.baidu.com/image/pic/item/342ac65c10385343498219169613b07eca8088bc.jpg");  
  79.         list_new.add(news5);  
  80.   
  81.         News news6 = new News();  
  82.         news6.setTitle("清纯的美女");  
  83.         news6.setContents("我不说什么,大家自己看");  
  84.         news6.setPicUrl("http://c.hiphotos.baidu.com/image/pic/item/a044ad345982b2b7a2f0f7cd33adcbef76099b48.jpg");  
  85.         list_new.add(news6);  
  86.   
  87.         News news7 = new News();  
  88.         news7.setTitle("清纯的美女");  
  89.         news7.setContents("我不说什么,大家自己看");  
  90.         news7.setPicUrl("http://e.hiphotos.baidu.com/image/pic/item/8b13632762d0f7031db73fdc0afa513d2697c5ad.jpg");  
  91.         list_new.add(news7);  
  92.   
  93.         News news8 = new News();  
  94.         news8.setTitle("清纯的美女");  
  95.         news8.setContents("我不说什么,大家自己看");  
  96.         news8.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/9825bc315c6034a857770337ce134954082376ea.jpg");  
  97.         list_new.add(news8);  
  98.         lAdapter.notifyDataSetChanged();  
  99.     }  
  100.   
  101.   
  102. }  

   哦,对了,还有它的布局。

  activity_list_view.xml

 

[html]  view plain  copy
 
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     tools:context="com.example.cg.picassolearn.ListViewActivity">  
  5.   
  6.     <ListView  
  7.         android:id="@+id/lv_main"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent">ListView>  
  10.   
  11. RelativeLayout>  

你可能感兴趣的:(android优化)