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:实现效果如下:




  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个使用 OkHttp、Retrofit 和 RxJava 的简单 Android 示例。 首先,你需要在你的 build.gradle 文件中添加以下依赖: ``` dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' } ``` 这样就可以使用 OkHttp、Retrofit 和 RxJava 的类和方法了。 接下来,你可以在你的代码中定义一个 Retrofit 接口: ``` public interface ApiService { @GET("users/{username}") Observable<User> getUser(@Path("username") String username); } ``` 在这个接口中,我们定义了一个 GET 请求,用于获取一个用户的信息。该请求的 URL 是 "https://api.github.com/users/{username}",其中 {username} 参数将会被替换为实际的用户名。接口返回的数据类型是 User,这是一个简单的类,如下所示: ``` public class User { public final String login; public final int id; public final String avatarUrl; public final String htmlUrl; public User(String login, int id, String avatarUrl, String htmlUrl) { this.login = login; this.id = id; this.avatarUrl = avatarUrl; this.htmlUrl = htmlUrl; } } ``` 现在,你可以在你的 Activity 或 Fragment 中调用这个接口: ``` ApiService apiService = RetrofitClient.getInstance().create(ApiService.class); apiService.getUser("octocat") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> { // 在这里处理获取到的用户信息 }, throwable -> { // 在这里处理请求失败的情况 }); ``` 该示例将会获取一个名为 "octocat" 的用户的信息,并在获取到数据后将其打印出来。需要注意的是,这个网络请求是在一个新的线程中执行的,以避免阻塞主线程。获取到数据后,我们转换到主线程中,并在观察者的 onNext 回调中处理数据。如果请求失败,则在观察者的 onError 回调中处理错误情况。 希望这个简单的示例可以帮助你理解如何在 Android 中使用 OkHttp、Retrofit 和 RxJava。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值