Picasso简介<一>
来源:互联网 发布:mysql 倒序 编辑:程序博客网 时间:2024/05/16 04:03
一,简介:
1简意:picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io.picasso/
2.突出优点:可以实现图片下载和缓存功能
在实际开发中异步图片加载时需考虑:
(1)在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题
(2)复杂的图片进行压缩,尽量减少内存的消耗
(3)实现内存缓存和二级硬盘缓存的效果
3.使用Picasso框架解决的图片下载中遇到的问题:
(1)在adapter中回收和取消当前下载
(2)使用最少的内存完成图片的转换
(3)自带内存和硬盘缓存
(4)图形转换,比如大小、旋转等
(5)加载网络资源和本地资源
(6)采用链式调用
4.与Universal-ImageLoader库对比:
1.都有高效的网络图片下载和缓存性能;
2.Universal-ImageLoader功能多,灵活使用配置;
3.Picasso使用复杂的图片压缩转换来尽可能的减少内存消耗;
4.在Adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个
二,简单使用
1.加载一张图片:
(1)添加依赖:点击app右键---》open module settings -->Dependencies下---右上角+号-->dependecy,输入picasso,选择com.squareup.picasso.Picasso
(2)使用,如,为按钮设置监听,imageview显示图片
布局:定义一个button,一个ImageView
代码:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Picasso.with(MainActivity.this).load(IMAGE_PATH).placeholder(R.mipmap.ic_launcher).fit().into(mImageView); } });
private final String IMAGE_PATH = "http://www.leawo.cn/attachment/201404/15/1077476_1397532112ke37.png";
效果:(添加网络权限)点击按钮后显示一张网络图片(但是在显示之前会有一个短暂的显示本地图片的过程)
2.用listView来显示url请求回来的数据:新闻图片+内容
(1)布局,定义ListView,在Activity中为该listView绑定控件id,
(2)自定义Picasso类:提供几个方法,如下:
public class PicassoUtils { /** * 指定图片宽高进行加载 * @param context * @param path * @param width * @param height * @param imageView */ public static void loadImageWithSize(Context context , String path , int width , int height , ImageView imageView){ Picasso.with(context).load(path).resize(width , height).centerCrop().into(imageView); } /** * 根据resID来加载图片 * @param context * @param path * @param resID * @param imageView */ public static void loadImageWithHolder(Context context , String path , int resID , ImageView imageView){ Picasso.with(context).load(path).placeholder(resID).into(imageView); } /** * 自定义裁剪类来加载图片 * @param context * @param path * @param imageView */ public static void loadImageWithCrop(Context context , String path , ImageView imageView){ Picasso.with(context).load(path).transform(new CropSquareTransformation()).into(imageView); } /** * 实现对图片的自定义裁剪 */ public static 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 != null){ source.recycle();//进行回收 } return result; //返回图片 } @Override public String key() { return "square()"; //自己取一个名字 } }}
(3)根据url,查看返回结果,创建实体类,这里取图片,summary,subject:
url:本来
http://litchiapi.jstv.com/api/GetFeeds?column=17&PageSize=20&pageIndex=1&val=AD908EDAB9C3ED111A58AF86542CCF50bean类:
public class NewsItem { private String subject ; //新闻主题 private String summary ; //新闻内容 private String cover ; //新闻图片 public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getCover() { return cover; } public void setCover(String cover) { this.cover = cover; }}
(4)创建访问任务,这里先用AsyncTask:代码如下:
/** * 异步任务实现:String,void,返回类型:一个list<NewsItem>集合 */ class MyTask extends AsyncTask<String , Void , List<NewsItem>>{ /** * 准备执行前:显示窗口进度条 */ @Override protected void onPreExecute() { super.onPreExecute(); //进度条窗口显示 dialog.show(); } @Override protected List<NewsItem> doInBackground(String... params) { //创建HttpClient对象 HttpClient httpClient = new DefaultHttpClient(); //创建HttpGet HttpGet httpGet = new HttpGet(params[0]); //创建返回对象 HttpResponse response = null; //创建List<NewsItem>集合 List<NewsItem> list = new ArrayList<>(); try { //获取返回结果对象Response response = httpClient.execute(httpGet); //判断是否请求成功 if(response.getStatusLine().getStatusCode() == 200){ //获取HttpEntity对象 HttpEntity entity = response.getEntity(); String json_value = EntityUtils.toString(entity , "utf-8"); //根据返回数据进行解析: //http://litchiapi.jstv.com/api/GetFeeds?column=17&PageSize=20&pageIndex=1&val=AD908EDAB9C3ED111A58AF86542CCF50 JSONArray jsonArray = new JSONObject(json_value) .getJSONObject("paramz").getJSONArray("feeds"); //获取每一条数据 for(int i = 0; i < jsonArray.length(); i++){ JSONObject element = jsonArray.getJSONObject(i).getJSONObject("data"); NewsItem item = new NewsItem(); item.setCover(element.getString("cover")); item.setSubject(element.getString("subject")); item.setSummary(element.getString("summary")); list.add(item); } } } catch (Exception e) { e.printStackTrace(); } return list; } @Override protected void onPostExecute(List<NewsItem> newsItems) { super.onPostExecute(newsItems); //完成时初始化MyAdapter adapter = new MyAdapter(newsItems); //为listView设置MyAdapter listView.setAdapter(adapter); //进度条窗口取消 dialog.cancel(); } }其中窗口进度条:
//定义进度条窗口 private ProgressDialog dialog ;
//创建进度条窗口对象 dialog = new ProgressDialog(this); //设置窗口标题 dialog.setTitle("loading......");
(5)自定义MyAdapter继承BaseAdapter:
/** * 自定义适配器 */ class MyAdapter extends BaseAdapter{ //List<NewsItem>集合 private List<NewsItem> data; /** * 初始化适配器 * @param data */ public MyAdapter(List<NewsItem> data){ this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { //创建MyViewHolder MyViewHolder holder = null; //一次 if(convertView == null){ holder = new MyViewHolder(); convertView = getLayoutInflater().inflate(R.layout.my_adapter_layout , parent , false); holder.cover = (ImageView)convertView.findViewById(R.id.cover_img); holder.subject = (TextView)convertView.findViewById(R.id.subject); holder.summary = (TextView)convertView.findViewById(R.id.summary); convertView.setTag(holder); Log.d(TAG , "convertView:" +position); }else { holder = (MyViewHolder)convertView.getTag(); } //分别设置图片,主题,内容 holder.subject.setText(data.get(position).getSubject()); //Log.d(TAG , data.get(position).getSubject()); holder.summary.setText(data.get(position).getSummary()); //Log.d(TAG , data.get(position).getSummary()); PicassoUtils.loadImageWithSize(ListViewActivity.this , "http://litchiapi.jstv.com" + data.get(position).getCover(), 400,300,holder.cover); return convertView; } }
MyViewHolder:
private static class MyViewHolder{ ImageView cover; TextView subject; TextView summary; }
MyAdapter的布局:就是一个图片,两个textView(对应新闻图片,标题,内容)
记得添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
(6)如果需要解决用户飞速下滑(即不想浏览中间某些新闻)时,picasso可以解决:
自定义onScrollListener类:
/** * 自定义OnScrollListener类 */ public class ListScroller implements AbsListView.OnScrollListener{ /** * 下滑状态改变时调用 * @param view * @param scrollState */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //创建Picasso final Picasso picasso = Picasso.with(ListViewActivity.this); //判断状态 if(scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL){ //更新 picasso.resumeTag(ListViewActivity.this); }else { //暂停 picasso.pauseTag(ListViewActivity.this); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }
为listView设置滑动监听:
//listView.setOnScrollListener(new ListScroller());即可以,截图略
附注代码地址:
https://github.com/maiyu-green/PicassoDemo
三,picasso的特点与常用设置方法:
通过以上的简单介绍,我们大概知道:
1.Picasso的特点:
总结以上,picasso的特点:
(1)自带内存和硬盘二级缓存功能
(2)加载本地资源,资产,SD卡及ContentProvider中的图片
(3)在Adapter中取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso解决了图片错位问题
(4)使用图片压缩尽可能的减少内存消耗
(5)图形转换操作,如变换大小,旋转等,提供了接口来让用户自定义转换操作
2.Picasso的常用设置方法
(1)加载本地资源、资产目录、SD卡已经ContentProvider的图像
基本语法:
Picasso.with(上下文).load(图片).into(ImageView)
加载图片资源:
//加载资源图片 Picasso.with(this).load(R.mipmap.ic_launcher).into(mImageView); //加载资产目录图片 Picasso.with(this).load("file://android_asset/logo.png").into(mImageView); //加载SD Card图片文件 Picasso.with(this).load(new File("路径")).into(mImageView); //加载网络图片 Picasso.with(this).load("url地址").into(mImageView);
(2)设置占位图片:下载前,下载出错时的图像,picasso会尝试3次请求,三次都失败会显示error方法:
Picasso.with(context) .load(url) //下载前显示图片 .placeholder(R.mipmap.ic_launcher) //下载出错显示图片 .error(R.mipmap.ic_launcher) .into(mImageView);(3)无淡入淡出:
.noFade()(4)图片重新调整大小:有两个方法
.resize(width,height)
.resizeDimen(targetWidthResId , targetHieghtResId)
(5)图片剪切类型:centerCrop,fit,centerInside
放在load之后:centerCrop与centerInside需要配合resize(),放在它之后,而fit不能再resize(),
centerCrop----会根据resize()方法的宽高进行裁剪
centerInside---会根据resize()方法的宽高进行比例缩放
如一张长方形图片,resize(100,100)后,centerCrop---结果正方形,centerInside结果--长方形缩小图
(6)自定义图形转换:为了更好的适配布局和减少存储空间,
利用transform方法:
/** * 实现对图片的自定义裁剪 */ public static 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 != null){ source.recycle();//进行回收 } return result; //返回图片 } @Override public String key() { return "square()"; //自己取一个名字 } }(7)图片旋转:
.rotate()方法
(8)设置图片质量对于不透明的图片可以使用RGB_565(一个像素点占用2个字节)来优化内存。
默认情况下Android使用ARGB_8888---一个像素点占用4个字节
用肉眼看,效果差不多
.config(Bitmap.Config.GRB_566)
(9)查看大图时放弃内存缓存memory cache:
Picasso默认会使用设备的15%的内存作为内存图片缓存,且现有的API无法清空内存缓存
在查看大图时放弃使用内存缓存,图片从网络下载完成后会自动缓存到磁盘中,加载会从磁盘中加载,这样可以加速内存回收
Picasso.with(getApplicationContext()) .load(url) //NO_CACHE指图片加载跳过从内存缓存查找,NO_STORE指图片存储时不往内存缓存中存储 .memoryPolicy(MemoryPolicy.NO_CACHE , MemoryPolicy.NO_STORE) .into(mImageView);
(10)设置tag标签:可以用来pause,resume和cancel访问
Picasso.with(this).pauseTag("pause标签"); Picasso.with(this).resumeTag("resume标签"); Picasso.with(this).cancelTag("标签");以下是在manifest中的设置:
(11)新进程中查看大图:
列表页的内存已经非常稳定,但查看大图时,常占用20多兆内存,加上现有进程内存,容易OOM
所以,在新进程中打开Activity成为比较巧取的避免oom的方式
<activity android:name=".MainActivity" android:process=":picture"/>只要在定义activity是添加process属性,即可在新进程中打开此activity,因为Picasso也将在新进程中创建基于新ApplicationContext的单例
3.Picasso在Application的常见设置
private void intoPicasso(){ Picasso picasso = new Picasso.Builder(this) //设置内存缓存大小 10m .memoryCache(new LruCache(10 << 20)) //下载图片的格式,采用rgb_565节省一半内存 .defaultBitmapConfig(Bitmap.Config.RGB_565) //配置下载器 //.downloader(new UrlConnectionDownloader()) //.downloader(new OkHttpDownloader()) .downloader(new MyDownLoader(getCacheDir() , 20 << 20)) //设置调试标志,位于左上角 //红色---代表从网络下载的图片 //蓝色--代表从磁盘缓存加载的图片 //绿色--代表从内存中加载的图片 .indicatorsEnabled(true) .build(); Picasso.setSingletonInstance(picasso); }
- Picasso简介<一>
- Picasso源码解析 一
- Picasso入门教程(一)
- Picasso的封装(一)
- Picasso的简介与使用
- Picasso使用简介及分析
- Picasso详细解析(一)
- Picasso使用学习(一)
- Android框架Picasso的使用简介
- Android网络加载框架:Picasso简介
- Picasso使用简介及分析(1)
- Picasso使用简介及分析(2)
- Picasso
- Picasso
- Picasso
- picasso
- Picasso
- Picasso
- 欢迎使用CSDN-markdown编辑器
- java中网络编程DatagramPacke类------UDP协议
- 用python 重命名文件夹下文件
- JS基础复习
- ADO.NET学习之SqlConnection,SqlCommand
- Picasso简介<一>
- vue2.0 自定义日期时间过滤器
- Bundle adjustment学习
- Redis和Memcache的区别分析
- 有哪些老鸟程序员知道而新手不知道的小技巧?
- Java动态代理
- 万能适配器
- Spring 之AOP AspectJ切入点语法详解(最全面、最详细。)
- 30. Substring with Concatenation of All Words