Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Picasso,一個強大的Android圖片下載緩存庫,OkHttpUtils的使用,二次封裝PicassoUtils實現微信精選

Picasso,一個強大的Android圖片下載緩存庫,OkHttpUtils的使用,二次封裝PicassoUtils實現微信精選

編輯:關於Android編程

 

這裡寫圖片描述

官網: http://square.github.io/picasso/

我們在上篇OkHttp的時候說過這個Picasso,學名畢加索,是Square公司開源的一個Android圖形緩存庫,而且使用起來也是非常的簡單,只要一行代碼就輕松搞定了,你會問,為什麼不介紹一下Glide?其實Glide我有時間也是會介紹的,剛好上篇我們用到了Picasso,所以就聊下這個,其實現在網上已經有很多關於Picasso的文章了,而Glide是Google的一位工程師根據Picasso做了很多優化的一個庫,孰強孰弱,大家這塊看看這個前輩的文章:

https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

好的,我們就正式的開始今天的文章吧!

一.准備工作

圖片緩存一直是個老掉牙的套路,即使眾多老司機,也有不少在這裡翻出,一言不合就大打出手的更加不計其數,我們在開發中要考慮很多種情況,比如

在ListView中,我們要對Adapter進行一系列優化,而圖片,要是沒在視圖中,我們應該取消這個不在視野中的圖片加載,否則會導致很多情況發生 圖片太多,OOM,復雜的圖片需要進行壓縮,盡量減少內存的消耗 圖片緩存,本地緩存,二級硬盤緩存等

這些都是諸多需要考慮的東西,我們不可否認,雖然是有很多的解決方案,但都不是非常有效的,直到這些庫的出現,乃至於優秀的庫出現,比如Picasso,Glide之內的,我們先新建一個項目——Picasso

這裡寫圖片描述

我們要想使用Picasso,需要配置他的依賴或者他的jar了<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjwvYmxvY2txdW90ZT4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160625/201606251057263.png" title="\" />

這裡,我就集成他的依賴便於使用了,畢竟老司機使用的是Android Studio

compile 'com.squareup.picasso:picasso:(insert latest version)'

再加個網絡權限

二.加載圖片

這裡,我們先從最簡單的開始,Picasso和Glide類似,都很方便,一句話搞定,加載的話,哪裡都會涉及,相信你也是會用的,所以我們從加載圖片開始,首先,我們在xml中定義一個布局

    

緊接著,我們直接看他的點擊事件

//下載圖片
 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的控件

 

然後我們就可以去解析這個接口,我們使用的是上節封裝的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的話,可以去看我的博文

OkHttp框架從入門到放棄,解析圖片使用Picasso裁剪,二次封裝OkHttpUtils,Post提交表單數據

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 mList;
    private WechatBean bean;

    public WechatAdapter(Context mContext, List 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();
        }
    }


好的,到這裡我們初步的解析算是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;
            }
        });
    }
}

哦,對了,別忘記了注冊

 

到這裡,整個項目下來算是做完了,我們可以運行一下

這裡寫圖片描述

到此,我們的博文算是結束了,當然,我還有很多知識沒講,需要大家一起去研究

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved