picasso介绍及使用

来源:互联网 发布:怎么把淘宝客链接转换 编辑:程序博客网 时间:2024/06/13 03:06

1.picasso简介

       picasso是一实现图片异步加载的第三方库。

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

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

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

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

2.使用方式

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

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

      使用Android studio进行开发,所以比较简单,只要引用compile 'com.squareup.picasso:picasso:2.5.2'即可

    (1)加载本地图片

     Picasso.with(this).load("file:///sdcard/Download/ddd.jpg").resize(100,100).rotate(180,0,0).into(mivPic);

    (2)加载网络图片

   

       load(mstrNetUrl).        //networkPolicy(NetworkPolicy.NO_CACHE,NetworkPolicy.NO_STORE).        memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE).        into(mivPic);
    (3)设置占位图片

   

  Picasso.with(context) .load(url) .placeholder(R.drawable.user_placeholder) .error(R.drawable.user_placeholder_error) .into(imageView);
整个库分为 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模块。

Dispatcher 负责分发和处理 Action,包括提交、暂停、继续、取消、网络状态变化、重试等等。

简单的讲就是 Picasso 收到加载及显示图片的任务,创建 Request 并将它交给 Dispatcher,Dispatcher 分发任务到具体 RequestHandler,任务通过 MemoryCache 及 Handler(数据获取接口) 获取图片,图片获取成功后通过 PicassoDrawable 显示到 Target 中。

需要注意的是上面 Data 的 File system 部分,Picasso 没有自定义本地缓存的接口,默认使用 http 的本地缓存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定义本地缓存就需要重定义 Downloader

3.使用内存优化

    (1)图片剪裁

   在列表页尽量使用裁剪后的图片,在查看大图模式下才加载完整的图片

Picasso.with( imageView.getContext() ).load(url).resize(dp2px(250),dp2px(250)).centerCrop().into(imageView);
  (2)查看大图放弃memory cache

  Picasso默认会使用设备的15%的内存作为内存图片缓存,且现有的api无法清空内存缓存。我们可以在查看大图时放弃使用内存缓存,图片从网络下载完成后会缓存到磁盘中,加载会从磁盘中加载,这样可以加速内存的回收。

Picasso.with(getApplication()).load(mURL).memoryPolicy(NO_CACHE, NO_STORE).into(imageView);

其中memoryPolicy的NO_CACHE是指图片加载时放弃在内存缓存中查找,NO_STORE是指图片加载完不缓存在内存中。

(3).RecycleableImageView

重写ImageView的onDetachedFromWindow方法,在它从屏幕中消失时回调,去掉drawable引用,能加快内存的回收。

public class RecyclerImageView extends ImageView{     ...    @Override        protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        setImageDrawable(null);       }}


可以看到使用了RecyclableImageView的实验在切换过程中产生的内存谷值明显优于ImageView,说明drawable更容易被回收。

(4).新进程中查看大图:

    列表页的内存已经非常稳定,但是查看大图时,大图往往占用了20+m内存,加上现有进程中的内存,非常容易oom,在新进程中打开Activity成为比较取巧的避免oom的方式。  

<activity android:name=".DetailActivity" android:process=":picture"/>
只要在AndroidManifest.xml中定义Activity时加入process属性,即可在新进程中打开此Activity。由此,picasso也将在新进程中创建基于新ApplicationContext的单例。

(5).列表页滑动优化

Object tag = new Object();Picasso.with( imageView.getContext() ).load(url).resize(dp2px(250),dp2px(250)).centerCrop().tag(tag).into(imageView);
例如在RecyclerView滑动时监听,处理不同的表现:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){    @Override    public void onScrollStateChanged(RecyclerView recyclerView, int newState)    {        if (newState == RecyclerView.SCROLL_STATE_IDLE)        {            Picasso.with(context).resumeTag(tag);        }        else        {            Picasso.with(context).pauseTag(tag);        }    }});

(6).RGB-565

对于不透明的图片可以使用RGB_565来优化内存。

默认情况下,Android使用ARGB_8888

Android中有四种,分别是:ALPHA_8:每个像素占用1byte内存ARGB_4444:每个像素占用2byte内存ARGB_8888:每个像素占用4byte内存RGB_565:每个像素占用2byte内存
RGB_565呈现结果与ARGB_8888接近,内存对比如下图


4.demo示例

效果图:


(1)先在app/build.gradle文件添加插件的依赖

    dependencies {            compile fileTree(dir: 'libs', include: ['*.jar'])            compile 'com.android.support:appcompat-v7:23.1.1'            compile 'com.squareup.picasso:picasso:2.5.2'       //这个就是      }  
activity_main.xml主页面布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"          xmlns:tools="http://schemas.android.com/tools"          android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context=".MainActivity"          android:orientation="vertical">          <ScrollView              android:layout_width="match_parent"              android:layout_height="match_parent">              <LinearLayout                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:orientation="vertical">                  <Button                      android:id="@+id/btn_listView"                      android:layout_width="match_parent"                      android:layout_height="wrap_content"                      android:gravity="center"                      android:text="ListView显示图片"/>                  <TextView                      android:layout_width="match_parent"                      android:layout_height="wrap_content"                      android:text="下图是根据ImageView大小,显示图片"/>                  <ImageView                      android:id="@+id/img_one"                      android:layout_width="150dp"                      android:layout_height="200dp" />                  <TextView                      android:layout_width="match_parent"                      android:layout_height="wrap_content"                      android:text="下图是通过程序代码,来显示图片大小"/>                  <ImageView                      android:id="@+id/img_two"                      android:layout_width="150dp"                      android:layout_height="100dp" />                  <TextView                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  android:text="加载本地的图片"/>                  <ImageView                      android:id="@+id/img_three"                      android:layout_width="50dp"                      android:layout_height="50dp" />                  <TextView                      android:layout_width="match_parent"                      android:layout_height="wrap_content"                      android:text="截取图片"/>                  <ImageView                      android:id="@+id/img_four"                      android:layout_width="150dp"                      android:layout_height="150dp" />              </LinearLayout>          </ScrollView>            </LinearLayout>  

MainActivity.java主页程序:

import android.os.Bundle;  import android.support.v7.app.AppCompatActivity;  import android.view.View;  import android.widget.Button;  import android.widget.ImageView;    import com.example.cg.picassolearn.untils.CropSquareTransformation;  import com.squareup.picasso.Picasso;    public class MainActivity extends AppCompatActivity implements View.OnClickListener {        private ImageView img_one;      private ImageView img_two;      private ImageView img_three;      private ImageView img_four;        private Button btn_listView;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            initControls();            initData();      }        /**      * 初始化控件      */      private void initControls() {            img_one = (ImageView)this.findViewById(R.id.img_one);          img_two = (ImageView)this.findViewById(R.id.img_two);          img_three = (ImageView)this.findViewById(R.id.img_three);          img_four = (ImageView)this.findViewById(R.id.img_four);          btn_listView = (Button)findViewById(R.id.btn_listView);          btn_listView.setOnClickListener(this);      }        /**      * 加载数据      */      private void initData()      {          /**          * 根据ImageView大小,显示图片          * .fit()                                  说明:控件不能设置成wrap_content,也就是必须有大小才行,fit()才让图片的宽高等于控件的宽高,设置fit(),不能再调用resize()          * .placeholder(R.drawable.topic_tom)      说明:当图片没有加载上的时候,显示的图片          * .error(R.drawable.topic_sky)            说明:当图片加载错误的时候,显示图片          * .into(img_one)                          说明:将图片加载到哪个控件中          */          Picasso.with(this).load("http://g.hiphotos.baidu.com/image/pic/item/c9fcc3cec3fdfc03e426845ed03f8794a5c226fd.jpg")                  .fit()                  .placeholder(R.drawable.topic_tom)                  .error(R.drawable.topic_sky)                  .into(img_one);          /**          * 通过程序代码,来显示图片大小          *.resize(200, 150)                        说明:为图片重新定义大小          *.centerCrop()                            说明:图片要填充整个控件,去两边留中间          */          Picasso.with(this).load("http://d.hiphotos.baidu.com/image/h%3D200/sign=745574b6a2ec08fa390014a769ee3d4d/cb8065380cd79123148b447daf345982b2b78054.jpg")                  .resize(200, 150)                  .centerCrop()                  .placeholder(R.drawable.topic_tom)                  .error(R.drawable.topic_sky)                  .into(img_two);            /**          * 加载本地数据库,图片的大小,取消于控件设置的大小          */          Picasso.with(this).load(R.drawable.topic_tom)                  .into(img_three);              /**          * 截取图片          * .transform(new CropSquareTransformation())        说明:通过程序截取图片          */          Picasso.with(this).load("http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg")                  .transform(new CropSquareTransformation())                  .placeholder(R.drawable.topic_tom)                  .error(R.drawable.topic_sky)                  .into(img_four);      }          @Override      public void onClick(View v) {          switch (v.getId())          {              case R.id.btn_listView:                  ListViewActivity.ListViewStar(this);                  break;          }      }  }  

在截取图片的地方,需要自己编写代码: CropSquareTransformation.java

import android.graphics.Bitmap;    import com.squareup.picasso.Transformation;    /**  * picasso的Transformation方法,对图片进行截取  * Created by cg on 2016/2/1.  */  public class CropSquareTransformation implements Transformation {        //截取从宽度和高度最小作为bitmap的宽度和高度      @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();//释放bitmap          }          return result;      }        @Override      public String key() {          return "square()";      }  }  

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

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

    News.java

public class News {        private String title;      private String contents;      private String PicUrl;        public News() {      }        public News(String title, String contents, String picUrl) {          this.title = title;          this.contents = contents;          PicUrl = picUrl;      }        public String getTitle() {          return title;      }        public void setTitle(String title) {          this.title = title;      }        public String getContents() {          return contents;      }        public void setContents(String contents) {          this.contents = contents;      }        public String getPicUrl() {          return PicUrl;      }        public void setPicUrl(String picUrl) {          PicUrl = picUrl;      }  }  

为ListView的Item添加布局

lv_item.xml:

    <?xml version="1.0" encoding="utf-8"?>      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:orientation="horizontal">                <LinearLayout              android:layout_width="0dp"              android:layout_height="110dp"              android:layout_weight="1"              android:gravity="center">              <ImageView                  android:id="@+id/item_pic"                  android:layout_width="100dp"                  android:layout_height="100dp" />          </LinearLayout>          <LinearLayout              android:layout_width="0dp"              android:layout_height="110dp"              android:layout_weight="3"              android:orientation="vertical">              <TextView                  android:id="@+id/txt_title"                  android:layout_width="match_parent"                  android:layout_height="0dp"                  android:layout_weight="1"/>              <TextView                  android:id="@+id/txt_content"                  android:layout_width="match_parent"                  android:layout_height="0dp"                  android:layout_weight="2"/>          </LinearLayout>            </LinearLayout>  

lv_Adapter.java

import android.content.Context;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.BaseAdapter;  import android.widget.ImageView;  import android.widget.TextView;    import com.example.cg.picassolearn.bean.News;  import com.squareup.picasso.Picasso;    import java.util.List;    /**  * ListView的Adapter  * Created by cg on 2016/2/1.  */  public class lv_Adapter extends BaseAdapter{        private List<News> list_new;      private LayoutInflater inflater;      private Context context;        public lv_Adapter(List<News> list_new, Context context) {          this.list_new = list_new;          this.context = context;          this.inflater = LayoutInflater.from(context);      }        @Override      public int getCount() {          return list_new.size();      }        @Override      public Object getItem(int position) {          return list_new.get(position);      }        @Override      public long getItemId(int position) {          return position;      }        @Override      public View getView(int position, View convertView, ViewGroup parent) {            ItemNews in;          if(convertView==null)          {              in = new ItemNews();                convertView = inflater.inflate(R.layout.lv_item,null);              in.title = (TextView)convertView.findViewById(R.id.txt_title);              in.contents = (TextView)convertView.findViewById(R.id.txt_content);              in.pic = (ImageView)convertView.findViewById(R.id.item_pic);                convertView.setTag(in);          }else          {              in = (ItemNews)convertView.getTag();          }            in.contents.setText(list_new.get(position).getContents());          in.title.setText(list_new.get(position).getTitle());            //注意这里,一行代码,就把图片加载上去了,而且你上下滚动listView你会发现什么,这个大家自己去体会          Picasso.with(context).load(list_new.get(position).getPicUrl()).fit()                  .placeholder(R.drawable.topic_tom)                  .error(R.drawable.topic_sky)                  .into(in.pic);            return convertView;      }          class ItemNews      {          TextView title;          ImageView pic;          TextView contents;      }  }  

ListViewActivity.java

import android.content.Context;  import android.content.Intent;  import android.os.Bundle;  import android.support.v7.app.AppCompatActivity;  import android.widget.ListView;    import com.example.cg.picassolearn.bean.News;    import java.util.ArrayList;  import java.util.List;    public class ListViewActivity extends AppCompatActivity {        private ListView lv_main;      private List<News> list_new;      private lv_Adapter lAdapter;        public static void ListViewStar(Context context)      {          Intent intent = new Intent(context,ListViewActivity.class);          context.startActivity(intent);      }        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_list_view);                    initControls();            initData();      }        /**      * 初始化控件      */      private void initControls() {          lv_main = (ListView)findViewById(R.id.lv_main);          list_new = new ArrayList<>();          lAdapter = new lv_Adapter(list_new,this);          lv_main.setAdapter(lAdapter);      }        /**      * 初始化数据      */      private void initData()      {          News news = new News();          news.setTitle("清纯的美女");          news.setContents("我不说什么,大家自己看");          news.setPicUrl("http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg");          list_new.add(news);            News news2 = new News();          news2.setTitle("好看的美女");          news2.setContents("我不说什么,大家自己看");          news2.setPicUrl("http://f.hiphotos.baidu.com/image/pic/item/11385343fbf2b211eee0554ac88065380dd78eec.jpg");          list_new.add(news2);            News news1 = new News();          news1.setTitle("狂野的美女");          news1.setContents("我不说什么,大家自己看");          news1.setPicUrl("http://a.hiphotos.baidu.com/image/h%3D200/sign=623f372f0b24ab18ff16e63705fbe69a/267f9e2f070828382f690e1dba99a9014c08f157.jpg");          list_new.add(news1);            News news4 = new News();          news4.setTitle("小护士");          news4.setContents("我不说什么,大家自己看");          news4.setPicUrl("http://f.hiphotos.baidu.com/image/pic/item/738b4710b912c8fc6684dceaf9039245d68821a5.jpg");          list_new.add(news4);            News news5 = new News();          news5.setTitle("古典的美女");          news5.setContents("我不说什么,大家自己看");          news5.setPicUrl("http://c.hiphotos.baidu.com/image/pic/item/342ac65c10385343498219169613b07eca8088bc.jpg");          list_new.add(news5);            News news6 = new News();          news6.setTitle("清纯的美女");          news6.setContents("我不说什么,大家自己看");          news6.setPicUrl("http://c.hiphotos.baidu.com/image/pic/item/a044ad345982b2b7a2f0f7cd33adcbef76099b48.jpg");          list_new.add(news6);            News news7 = new News();          news7.setTitle("清纯的美女");          news7.setContents("我不说什么,大家自己看");          news7.setPicUrl("http://e.hiphotos.baidu.com/image/pic/item/8b13632762d0f7031db73fdc0afa513d2697c5ad.jpg");          list_new.add(news7);            News news8 = new News();          news8.setTitle("清纯的美女");          news8.setContents("我不说什么,大家自己看");          news8.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/9825bc315c6034a857770337ce134954082376ea.jpg");          list_new.add(news8);          lAdapter.notifyDataSetChanged();      }      }  

对应的布局:

activity_list_view.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"          xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context="com.example.cg.picassolearn.ListViewActivity">                <ListView              android:id="@+id/lv_main"              android:layout_width="match_parent"              android:layout_height="match_parent"></ListView>            </RelativeLayout>  


    

   


0 0
原创粉丝点击