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,所以如果需要自定义本地缓存就需要重定义 Downloader3.使用内存优化
(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.javapublic 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>
- picasso介绍及使用
- Picasso使用简介及分析
- Picasso和Glide的介绍及比较
- Picasso的简单介绍和使用
- Picasso的使用及原理详解
- Picasso使用详解及源码解析
- picasso-基本使用及环境配置
- Picasso使用简介及分析(1)
- Picasso使用简介及分析(2)
- Picasso的简单使用及封装
- Picasso使用
- picasso使用
- picasso使用
- 图片加载框架简单介绍<二> Picasso 的基本使用
- Android框架Picasso介绍
- Picasso图片框架加载图片 使用及缓存问题
- Picasso 图片加载及缓存的使用心得
- Android框架之Picasso和Glide的使用及区别
- zookeeper入门之curator框架--原子性操作
- ros::spin() 与ros::spinOnce()
- tableview 设置交替色
- 【机器学习】评价指标
- PyOdps在交互式环境下的使用,让探索ODPS数据更容易些
- picasso介绍及使用
- Android Studio解决Error:Dependency Puddings:videosdk1218:unspecified on project app resolves to an APK
- 安卓数据存储
- Ny106背包问题
- servlet过滤器的xml配置和注解方式对比
- 在linux上安装nginx
- 开始我的视频学习之旅----前言
- 数码管右移
- Android 知识点锦集