毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
我们在上篇OkHttp的时候说过这个Picasso,学名毕加索,是Square公司开源的一个Android图形缓存库,而且使用起来也是非常的简单,只要一行代码就轻松搞定了,你会问,为什么不介绍一下Glide?其实Glide我有时间也是会介绍的,刚好上篇我们用到了Picasso,所以就聊下这个,其实现在网上已经有很多关于Picasso的文章了,而Glide是Google的一位工程师根据Picasso做了很多优化的一个库,孰强孰弱,大家这块看看这个前辈的文章:
好的,我们就正式的开始今天的文章吧!
一.准备工作
图片缓存一直是个老掉牙的套路,即使众多老司机,也有不少在这里翻出,一言不合就大打出手的更加不计其数,我们在开发中要考虑很多种情况,比如
- 在ListView中,我们要对Adapter进行一系列优化,而图片,要是没在视图中,我们应该取消这个不在视野中的图片加载,否则会导致很多情况发生
- 图片太多,OOM,复杂的图片需要进行压缩,尽量减少内存的消耗
- 图片缓存,本地缓存,二级硬盘缓存等
这些都是诸多需要考虑的东西,我们不可否认,虽然是有很多的解决方案,但都不是非常有效的,直到这些库的出现,乃至于优秀的库出现,比如Picasso,Glide之内的,我们先新建一个项目——Picasso
我们要想使用Picasso,需要配置他的依赖或者他的jar了
这里,我就集成他的依赖便于使用了,毕竟老司机使用的是Android Studio
compile 'com.squareup.picasso:picasso:(insert latest version)'
再加个网络权限
<uses-permission android:name="android.permission.INTERNET"/>
二.加载图片
这里,我们先从最简单的开始,Picasso和Glide类似,都很方便,一句话搞定,加载的话,哪里都会涉及,相信你也是会用的,所以我们从加载图片开始,首先,我们在xml中定义一个布局
<Button
android:id="@+id/btn_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="加载图片" />
<ImageView
android:id="@+id/iv_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
紧接着,我们直接看他的点击事件
//下载图片
btn_loading.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Picasso.with(MainActivity.this).load(url).into(iv_img);
}
});
可以看到,就一行代码,我的天哪,就是这么简单,而且你后面还可以增加一些属性,包括对图片翻转,定义大小,加载失败显示什么图片之类的,这个就详细的去看一下他的API文档就行,不是跟多,我们来看一下他运行的效果
OK,简单的加载我们就学会了
二.PicassoUtils
既然我们使用会了,现在应该去玩玩他的缓存了,这里我们直接封装成一个工具类岂不美哉?好的,我们开始封装,当然,我们也会封装我们OkHttp中说道的裁剪功能等:而且我们还会使用到我们上次封装的OkHttpUtils类
首先,我们封装与喜爱工具类,方法的作用也都有详细的注释
package com.lgl.picasso;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Transformation;
/**
* Picasso工具类
* Created by LGL on 2016/6/23.
*/
public class PicassoUtils {
/**
* 指定大小加载图片
*
* @param mContext 上下文
* @param path 图片路径
* @param width 宽
* @param height 高
* @param mImageView 控件
*/
public static void loadImageViewSize(Context mContext, String path, int width, int height, ImageView mImageView) {
Picasso.with(mContext).load(path).resize(width, height).centerCrop().into(mImageView);
}
/**
* 加载有默认图片
*
* @param mContext 上下文
* @param path 图片路径
* @param resId 默认图片资源
* @param mImageView 控件
*/
public static void loadImageViewHolder(Context mContext, String path, int resId, ImageView mImageView) {
Picasso.with(mContext).load(path).fit().placeholder(resId).into(mImageView);
}
/**
* 裁剪图片
*
* @param mContext 上下文
* @param path 图片路径
* @param mImageView 控件
*/
public static void loadImageViewCrop(Context mContext, String path, ImageView mImageView) {
Picasso.with(mContext).load(path).transform(new CropImageView()).into(mImageView);
}
/**
* 自定义图片裁剪
*/
public static class CropImageView 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 newBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (newBitmap != null) {
//内存回收
source.recycle();
}
return newBitmap;
}
@Override
public String key() {
return "lgl";
}
}
}
三.微信精选
既然工具类写完了,我们就要开工了,我们这次做的是一个微信精选,接口我是从聚合数据拿的
//微信精选接口
private String wechat_url = "http://v.juhe.cn/weixin/query?key=78f723dccf85aea324a3cf0daac97f35";
我们在xml中定义一个listview的控件
<ListView
android:id="@+id/mListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
然后我们就可以去解析这个接口,我们使用的是上节封装的OkHttp
OkHttpUtils okHttp = OkHttpUtils.getInstance();
okHttp.syncJsonStringByURL(wechat_url, new OkHttpUtils.FuncJsonString() {
@Override
public void onResponse(String result) {
Log.i("json", result);
getJson(result);
}
});
如果你还不知道怎么去使用OkHttp的话,可以去看我的博文
OK,我们解析得到json,现在就要根据json去写个实体类了
package com.lgl.picasso;
/**
* 微信精选
*
* @author LGL
*/
public class WechatBean {
private String url;
private String title;
private String type;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "WechatBean [url=" + url + ", title=" + title + ", type=" + type
+ "]";
}
}
做完实体类,我们有数据封装方式了,那就直接去写Adapter吧
package com.lgl.picasso;
import android.content.Context;
import android.text.TextUtils;
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 java.util.List;
/**
* 数据源
*
* @author LGL
*/
public class WechatAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater inflater;
private List<WechatBean> mList;
private WechatBean bean;
public WechatAdapter(Context mContext, List<WechatBean> mList) {
this.mContext = mContext;
this.mList = mList;
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHoldwe vHoldwe = null;
if (convertView == null) {
vHoldwe = new ViewHoldwe();
convertView = inflater.inflate(R.layout.wechatist_item, null);
vHoldwe.iv_url = (ImageView) convertView
.findViewById(R.id.iv_url);
vHoldwe.tv_title = (TextView) convertView
.findViewById(R.id.tv_title);
vHoldwe.tv_type = (TextView) convertView.findViewById(R.id.tv_type);
convertView.setTag(vHoldwe);
} else {
vHoldwe = (ViewHoldwe) convertView.getTag();
}
bean = mList.get(position);
vHoldwe.tv_title.setText(bean.getTitle());
vHoldwe.tv_type.setText(bean.getType());
if(!TextUtils.isEmpty(bean.getUrl())){
PicassoUtils.loadImageViewSize(mContext, bean.getUrl(),150,100, vHoldwe.iv_url);
}else{
vHoldwe.iv_url.setImageResource(R.mipmap.ic_launcher);
}
return convertView;
}
class ViewHoldwe {
private ImageView iv_url;
private TextView tv_title;
private TextView tv_type;
}
}
Adapter算是老生常谈的问题了,我们这里使用到了我们封装好的Picasso工具类,到这里我们就可以去看一下怎么解析json了
/**
* 解析Json
*
* @param json
*/
private void getJson(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONObject jsonresult = jsonObject.getJSONObject("result");
JSONArray jArray = jsonresult.getJSONArray("list");
for (int i = 0; i < jArray.length(); i++) {
JSONObject jb = (JSONObject) jArray.get(i);
WechatBean bean = new WechatBean();
bean.setTitle(jb.getString("title"));
bean.setType(jb.getString("source"));
bean.setUrl(jb.getString("firstImg"));
mList.add(bean);
//存起来
urlList.add(jb.getString("url"));
titleList.add(jb.getString("title"));
}
adapter = new WechatAdapter(this, mList);
mListView.setAdapter(adapter);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
解析json还是比较简单的,如果不会,可以移步我的博文
好的,到这里我们初步的解析算是OK了,我们来看下效果
四.缓存优化
这里做一些简单的处理就好了,首先,我们滑动视图,如果我们看不见的视图我们可以不加载,这样慢慢的加载,对我们app提升还是很有帮助的,所以我们要设置监听
//监听
mListView.setOnScrollListener(new ListScroller());
关于它的回调
/**
* 滚动监听
*/
public class ListScroller implements AbsListView.OnScrollListener {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
final Picasso picasso = Picasso.with(MainActivity.this);
if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
//重置
picasso.resumeTag(MainActivity.this);
} else {
//暂停
picasso.pauseTag(MainActivity.this);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
}
当然,还有我们既然是一个新闻客户端,怎么的,也要可以看新闻才对,对吧,所以我们新建一个WebViewActivity,首先传值跳转
//监听
mListView.setOnScrollListener(new ListScroller());
//跳转
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MainActivity.this, WebViewActivity.class);
i.putExtra("title", titleList.get(position));
i.putExtra("url", urlList.get(position));
startActivity(i);
}
});
而WebViewActivity的代码就比较少了
package com.lgl.picasso;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
/**
* 客户端
* Created by LGL on 2016/6/23.
*/
public class WebViewActivity extends AppCompatActivity{
private WebView mWebView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
mWebView = (WebView) findViewById(R.id.mWebView);
Intent i = getIntent();
getSupportActionBar().setTitle(i.getStringExtra("title"));
mWebView.loadUrl(i.getStringExtra("url"));
//本地显示
mWebView.setWebViewClient(new android.webkit.WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
}
哦,对了,别忘记了注册
<activity android:name=".WebViewActivity"/>
到这里,整个项目下来算是做完了,我们可以运行一下
到此,我们的博文算是结束了,当然,我还有很多知识没讲,需要大家一起去研究
如果对我活着Android技术感兴趣,欢迎加群:555974449
Demo下载:http://download.csdn.net/detail/qq_26787115/9557996
毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选的更多相关文章
- picasso_强大的Android图片下载缓存库
tag: android pic skill date: 2016/07/09 title: picasso-强大的Android图片下载缓存库 [本文转载自:泡在网上的日子 参考:http://bl ...
- picasso-强大的Android图片下载缓存库
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! pica ...
- android开源项目:图片下载缓存库picasso
picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能. picasso有如下特性: 在a ...
- Android 图片加载库Glide 实战(二),占位符,缓存,转换自签名高级实战
http://blog.csdn.net/sk719887916/article/details/40073747 请尊重原创 : skay <Android 图片加载库Glide 实战(一), ...
- 如何使用picasso 对Android图片下载缓存
相比较其他,picasso的图片缓存更加简单一些,他只需要一行代码就可以表述:导入相关jar包 Picasso.with(context).load("图片路径").into(Im ...
- fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)
[Android开发经验]FaceBook推出的Android图片加载库-Fresco 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件 ...
- FaceBook推出的Android图片加载库-Fresco
FaceBook推出的Android图片加载库-Fresco 原文链接:Introducing Fresco: A new image library for Android 译者 : ZhaoKai ...
- Android图片加载库的理解
前言 这是“基础自测”系列的第三篇文章,以Android开发需要熟悉的20个技术点为切入点,本篇重点讲讲Android中的ImageLoader这个库的一些理解,在Android上最让人头疼是 ...
- android图片加载库Glide
什么是Glide? Glide是一个加载图片的库,作者是bumptech,它是在泰国举行的google 开发者论坛上google为我们介绍的,这个库被广泛的运用在google的开源项目中. Glide ...
随机推荐
- drools 手动创建kmoudle.xml文件
@Test public void test() { KieServices kieServices = KieServices.Factory.get(); KieResources resourc ...
- Python学习札记-eval函数
eval()函数 eval()官方文档里面给出来的功能解释是:将字符串string对象转化为有效的表达式参与求值运算返回计算结果 语法上:调用的是:eval(expression,globals=No ...
- java处理数据库不支持的emoji
一般数据库的编码是utf8,utf8是不支持存储表情符的,当存入的微信昵称带有表情符时就会出现乱码情况,有两种解决方法: 1.mysql数据库升级到5.5版本以上,utf8改为utf8mb4,utf8 ...
- java利用自定义类型对树形数据类型进行排序
前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...
- 设计模式之中介者模式(Mediator )
中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...
- Docker 网络
Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair).建议先熟悉了解这两部分的基本概念再阅读本章. 基本原理 首先,要实现网络通信,机器需要 ...
- Python3 基础语法
编码 默认情况下,Python 3源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串. 当然你也可以为源码文件指定不同的编码: # -*- coding: cp-1252 -*- 标 ...
- GDAL打开mdb文件失败解决方法
使用GDAL打开mdb文件时提示下面错误信息: ERROR 1: Unable to initialize ODBC connection to DSN for DRIVER=Microsoft Ac ...
- 剑指Offer——知识点储备-Java基础
剑指Offer--知识点储备-Java基础 网址来源: http://www.nowcoder.com/discuss/5949?type=0&order=0&pos=4&pa ...
- DJango内建模板转向jinja2的小脚本
import re,os def org(path=os.getcwd(),fs=None,preview=True): fs = fs or [] for root,dirs,files in os ...