Android_OkHttp+Picasso+RecyclerView实现网络图片下载瀑布流

Posted 9编程小王子9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android_OkHttp+Picasso+RecyclerView实现网络图片下载瀑布流相关的知识,希望对你有一定的参考价值。

转发标明出处:http://blog.csdn.net/zcr317121966/article/details/52331534

此效果和上篇答题相同,思路一致,是一种效果的两种实现方式,只是用到的框架不同,内部差异不同。

也是大致描述以下实现步骤:

导入的架包有squareup-okhttp,squareup-okio,squareup-picasso,goodle-Gson和V7-resyclerview.

总共需要也是四个类:1:MainActivity类:

2:OkHttpUtils类  OkHttp工具类,封装了实现网络数据下载返回任意bean类型的方法,并且实现对象的单例

3:MyAdapterl类:用于适配recyclerview的适配器。

4:TestBean类,数据存储类接受json数据返回的该类对象。

代码如下:

1:MainActivity类:

package com.example.okhttppicassorecyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;


import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity 

    //获取的json数据中的数据集合
    private List<TestBean.DataBean.WallpaperListInfoBean>  list = new ArrayList<>();

    //创建一个list集合存储recyclerview中的图片的高度
    private List<Integer> heights =  new ArrayList<>();

    //声明recyclerview引用
    private RecyclerView mRecyclerView;

    //声明自定义请求类
    private MyAdapter adapter;


    //用插件自动生成初始化view代码的方法
    private void assignViews() 

        mRecyclerView= (RecyclerView) findViewById(R.id.recyclerview);

        //设置recyclerview要实现的类型为StaggeredGrid瀑布流类型
        //并再构造方法中指定列数3,纵向排列
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,RecyclerView.VERTICAL));

    



    //网络请求数据的网址
    private String url ="http://bz.budejie.com/?typeid=2&ver=3.4.3&no_cry=1&client=android&c=wallPaper&a=random&bigid=0";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化控件
        assignViews();

        //开启网络下载数据的方法
        startTask();

    

    private void startTask() 

        //通过类名直接调用静态方法获取单例对象再调用getBeanOfOK()方法传入参数通过接口回调获取数据
        OkHttpUtils.getInstance().getBeanOfOk(this, url, TestBean.class,
                new OkHttpUtils.CallBack<TestBean>() 
                    @Override
                    public void getData(TestBean testBean) 

                        Log.i("===", "getData: "+testBean.toString());
                        if(testBean!=null)

                            //如果不为空用本地list接收
                            list.addAll(testBean.getData().getWallpaperListInfo());

                            //数据一旦回调成功初始化数据源和适配器
                            initHights();

                            initAdapter();
                        
                    
                );


    

    private void initAdapter() 


        //创建自定义适配器对象
        adapter = new MyAdapter(this,list,heights);

        //设置recyclerview适配器
        mRecyclerView.setAdapter(adapter);

        //刷新适配器
        adapter.notifyDataSetChanged();

    

    private void initHights() 
        //设置随机数
        Random random = new Random();

        for (int i = 0; i < list.size(); i++) 

            //集合中存储每个回调图片对应的随机高度
            heights.add(random.nextInt(200)+200);
        

    


2:OkHttpUtils类  OkHttp工具类,封装了实现网络数据下载返回任意bean类型的方法


package com.example.okhttppicassorecyclerview;

import android.app.Activity;

import com.google.gson.Gson;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by Administrator on 2016/8/24 0024.
 */

//OkHttpUtils工具类,用于 用OkHttp框架获取网络数据并通过添加范型的静态方法返回不同
    //bean对象的数据
public class OkHttpUtils 

    //声明OkHttpClient引用
    private OkHttpClient client;

    //私有化构造方法
    private OkHttpUtils()

        //创建client对象只在创建OkHttpUitls对象时创建一次
        client = new OkHttpClient();

    

    //声明静态OkHttpUtils引用
    private static OkHttpUtils utils;

    //单例设计模式让外部始终获得的是一个OkHttpUtils对象
    public static OkHttpUtils getInstance() 

        //双重判断加上同步锁可以解决线程安全问题
        if(utils==null)
            synchronized (OkHttpUtils.class)
                if(utils==null)

                    //一旦判断没有创建过此类的对象就创建一次并返回
                    utils = new OkHttpUtils();

                    return utils;
                
            
        
        return utils;
    

    //定义一个callback接口并定义范型(适用于任意类的返回对象)用于接口回调
    interface CallBack<T>

        //定义回调方法
        void getData(T t);
    

    //创建万能的数据请求类,形参为四个activity对象,网址url,和得到数据的bean类为范型的class对象,实现接口的类对象
    public <T extends Object>void getBeanOfOk(final Activity activity, String url, final Class<T> clazz, final CallBack<T> callback)

        //创建request请求对象,设置其方式get,网址url
        Request request = new Request.Builder().get().url(url).build();

        //通过client的newCall方法传入request,并调用enqueue求求数据
        client.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(Call call, IOException e) 

            

            @Override
            public void onResponse(Call call, Response response) throws IOException 

                //通过返回的response对象的body()和string()方法得到获取的json字符串
                String json = response.body().string();

                //通过Gson解析得到解析后任意类对象
                final T t  = new Gson().fromJson(json,clazz);

                //由于子线程中不能更新UI所以我们用activity对象调用方法回到主线程
                activity.runOnUiThread(new Runnable() 
                    @Override
                    public void run() 
                        if(t!=null)
                            //并用过接口回调传回数据
                            callback.getData(t);
                        
                    
                );
            
        );
    



3:MyAdapterl类:用于适配recyclerview的适配器。

package com.example.okhttppicassorecyclerview;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

import java.util.List;

/**
 * Created by Administrator on 2016/8/24 0024.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> 

    //声明两个集合用于接受构造方法传来的参数在本地使用
    private List<TestBean.DataBean.WallpaperListInfoBean> list;

    private List<Integer> heights;

    //声明上下文引用,用于加载布局文件
    private Context context;

    //用构造方法传入需要的参数,
    public MyAdapter(Context context, List<TestBean.DataBean.WallpaperListInfoBean> list, List<Integer> heights) 
        this.context = context;
        this.list = list;
        this.heights = heights;

    

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
        //返回MyViewHolder对象,通过构造方法传入加载布局文件得到的view对象
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
    

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) 
        //通过itemview得到每个图片的pararms对象
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();

        //将高度修改为传入的随机高度
        params.height = heights.get(position);

        //设置修改参数
        holder.itemView.setLayoutParams(params);


//        holder.iv.setImageResource(R.mipmap.ic_launcher);

        //用过Picasso框架对图片处理并显示到iv上
        //用with()方法初始化,,
        Picasso.with(context)
                //load()下载图片
                .load(list.get(position).getWallPaperMiddle())

                //下载中显示的图片
                .placeholder(R.mipmap.ic_launcher)

                //下载失败显示的图片
                .error(R.mipmap.ic_launcher)

                //init()显示到指定控件
                .into(holder.iv);

    

    @Override
    public int getItemCount() 

        //返回数据源大小
        return list.size();
    

    //自定义MyViewHolder类用于复用
    class MyViewHolder extends RecyclerView.ViewHolder 
        //声明imageview对象
        private ImageView iv;

        //构造方法中初始化imageview对象
        public MyViewHolder(View itemView) 
            super(itemView);
            iv = (ImageView) itemView.findViewById(R.id.imageview);
        
    



4:TestBean类,数据存储类接受json数据返回的该类对象。

package com.example.okhttppicassorecyclerview;

import java.util.List;

/**
 * Created by bane on 2016/8/24 0024.
 */


//bean类,通过网址的json数据用插件GsonFromt自动勾选需要的数据生成
public class TestBean 


    private DataBean data;

    public DataBean getData() 
        return data;
    

    public void setData(DataBean data) 
        this.data = data;
    

    public static class DataBean 
        /**
         * ID : 10745507
         * PicName : 10745507.jpg
         * pic_path : /picture1/M00/0A/FA/wKiFR1NRAsiAF85CAAXZwUlD8Tk121.jpg
         * BigCategoryId : 1041
         * SecondCategoryId : 2661
         * CreateTime : 2014-04-18 18:44:01
         * passtime : 2014-03-19 18:47:34
         * UserName : sprit_admin
         * DownloadCount : 9
         * GoodCount : 9
         * tags :
         * WallPaperMiddle : http://bzpic.spriteapp.cn/250x445/picture1/M00/0A/FA/wKiFR1NRAsiAF85CAAXZwUlD8Tk121.jpg
         * WallPaperBig : http://bzpic.spriteapp.cn/1080x1920/picture1/M00/0A/FA/wKiFR1NRAsiAF85CAAXZwUlD8Tk121.jpg
         * WallPaperDownloadPath : http://bzpic.spriteapp.cn/1080x1920/picture1/M00/0A/FA/wKiFR1NRAsiAF85CAAXZwUlD8Tk121.jpg
         * WallPaperSource : http://bzpic.spriteapp.cn/744x1392/picture1/M00/0A/FA/wKiFR1NRAsiAF85CAAXZwUlD8Tk121.jpg
         * weixin_url : http://www.budejie.com/bz/bdj-10745507.html?wx.qq.com
         */

        private List<WallpaperListInfoBean> WallpaperListInfo;

        public List<WallpaperListInfoBean> getWallpaperListInfo() 
            return WallpaperListInfo;
        

        public void setWallpaperListInfo(List<WallpaperListInfoBean> WallpaperListInfo) 
            this.WallpaperListInfo = WallpaperListInfo;
        

        public static class WallpaperListInfoBean 
            private int ID;
            private String tags;
            private String WallPaperMiddle;
            private String WallPaperBig;
            private String WallPaperDownloadPath;

            public int getID() 
                return ID;
            

            public void setID(int ID) 
                this.ID = ID;
            

            public String getTags() 
                return tags;
            

            public void setTags(String tags) 
                this.tags = tags;
            

            public String getWallPaperMiddle() 
                return WallPaperMiddle;
            

            public void setWallPaperMiddle(String WallPaperMiddle) 
                this.WallPaperMiddle = WallPaperMiddle;
            

            public String getWallPaperBig() 
                return WallPaperBig;
            

            public void setWallPaperBig(String WallPaperBig) 
                this.WallPaperBig = WallPaperBig;
            

            public String getWallPaperDownloadPath() 
                return WallPaperDownloadPath;
            

            public void setWallPaperDownloadPath(String WallPaperDownloadPath) 
                this.WallPaperDownloadPath = WallPaperDownloadPath;
            

            @Override
            public String toString() 
                return "WallpaperListInfoBean" +
                        "ID=" + ID +
                        ", tags='" + tags + '\\'' +
                        ", WallPaperMiddle='" + WallPaperMiddle + '\\'' +
                        ", WallPaperBig='" + WallPaperBig + '\\'' +
                        ", WallPaperDownloadPath='" + WallPaperDownloadPath + '\\'' +
                        '';
            
        
    


5:mxl配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.okhttppicassorecyclerview">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

6:layout布局文件activity_main和item

<?xml version="1.0" encoding="utf-8"?>
<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.okhttppicassorecyclerview.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />
</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="3dp"
    android:layout_marginRight="3dp"
    >
<ImageView
    android:id="@+id/imageview"

    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    />
</RelativeLayout>



7:实现效果如下:





以上是关于Android_OkHttp+Picasso+RecyclerView实现网络图片下载瀑布流的主要内容,如果未能解决你的问题,请参考以下文章

Picasso源码解析

Picasso源码解析

Android图片加载框架Picasso最全使用教程 五

Android图片加载框架Picasso最全使用教程 五

Picasso源码解析

Picasso源码解析