使用glide图片加载框架将网络图片展示并在listview中

来源:互联网 发布:淘宝联盟能贷款吗 编辑:程序博客网 时间:2024/05/21 20:25

在实际项目中,经常有需要将服务器端返回的图片的url地址显示在listview中的情况,如果我们自己去实现的话,大致思路是:1、创建JavaBean2、创建adapter3、创建http请求类4、在活动中对http返回的消息进行解析5、获取到图片的url时开启一个线程来再开启一次网络来下次图片并存放再bitmap中6、在adapter中使用image.setImageBitmap的方法将活动中的bitmap设置进去;博主第一次就是这么实现的,我在测试下载一张的时候,是没有什么问题的,但是当数量升至十张时,出现了多张图片显示不全的情况,心里就想,好麻烦哇,有没有什么东西能代替我们做第五步就好了,于是,我找到了glide(给力的),不得不说,这玩意还真给力,那就先看效果图


我实际是写了加载十张图片在listview中的,但是csdn限制的图片格式在2m以内,所以只能截取一小段,不过后面也都是图片,重点是效果.

在这里不得不说的是,如果用博主的第一个办法,虽然能加载图片,却加载不了gif,只能显示gif的第一帧画面,如果要用imageview显示gif的话,还要把这个gif一帧一帧的保存起来,然后再开启一个线程又一帧一帧的播放出来,是不是感觉很麻烦,但是这些事glide都帮我们做好了,glide可以通过判断图片的格式来选择不同的方式进行加载,这点在效果图中就能体现,十分方便。接下来就将如何实现这个效果

实现思路其实和上面一样,但是我们不需要传bitmap,因为glide帮我们完成了第5步,我们只需要获取图片url,然后传递到adapter中,在那里,有我们获取的imagview的实例,就可以通过glide设置图片上去啦。

第一部分:准备工具

1、下载glide(网上很多,我用的是3.7的)

2、在project工程目录下的libs中将下载好的glide添加进去

3、添加依赖

compile 'com.github.bumptech.glide:glide:3.7.0'
4、当然数据源了,我用的是聚合数据的免费接口--笑话大全,虽然一天只能用一百次,但是测试是绰绰有余了,如何使用我在EveryDay这个项目中也有讲解,所以不再赘述(友情提示:笑话大全有几个接口,我用的是第五个,随机获取笑话)

      第二部分:功能实现

      开头讲的步骤是业务逻辑的步骤,实际中我们还要写布局

1、主布局,就是一个listview

2、子项布局

       代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout    android:orientation="vertical"    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/textTitle"        android:layout_marginTop="15dp"        android:gravity="center"        android:text="这是图片的标题"        android:textSize="20sp"        android:layout_width="match_parent"        android:layout_height="wrap_content" /><ImageView    android:id="@+id/imageView"    android:src="@mipmap/ic_launcher"    android:layout_marginTop="15dp"    android:layout_width="match_parent"    android:layout_height="200dp" /></LinearLayout>
效果图:


3、javabean

package com.example1.ikecin.mypro.Adapter;import android.graphics.Bitmap;import android.widget.ImageView;import android.widget.TextView;/** * Created by awei on 2017/12/13. */public class Other_1_Bean {    //图片标题    private String textTitle;    private String url;    public String getTextTitle() {        return textTitle;    }    public void setTextTitle(String textTitle) {        this.textTitle = textTitle;    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }}

4、adapter(重中之重)

package com.example1.ikecin.mypro.Adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import com.bumptech.glide.Glide;import com.bumptech.glide.load.engine.DiskCacheStrategy;import com.example1.ikecin.mypro.R;import java.util.List;/** * Created by awei on 2017/12/13. */public class Other_1_Adapter extends BaseAdapter {    private LinearLayout mLinearLayout;    private Context mContext;    private List<Other_1_Bean> mList;    public Other_1_Adapter(Context mContext, List<Other_1_Bean> mList) {        this.mContext = mContext;        this.mList = mList;    }    @Override    public int getCount() {        return mList.size();    }    @Override    public Object getItem(int i) {        return mList.get(i);    }    @Override    public long getItemId(int i) {        return i;    }    @Override    public View getView(int i, View view, ViewGroup viewGroup) {        ViewHolder viewHolder;        if (view == null) {//判断view是否可以重载            viewHolder = new ViewHolder();            LayoutInflater inflater = LayoutInflater.from(mContext);            mLinearLayout = (LinearLayout) inflater.inflate(R.layout.view_list_view_other1_item, null);            //获取id            viewHolder.textTitle = mLinearLayout.findViewById(R.id.textTitle);            viewHolder.imageView = mLinearLayout.findViewById(R.id.imageView);            //设置数据            viewHolder.textTitle.setText(mList.get(i).getTextTitle());            //使用glide加载图片            Glide.with(mContext)                    .load(mList.get(i).getUrl()) //加载地址                    .placeholder(R.drawable.bitmap)//加载未完成时显示占位图                    .diskCacheStrategy(DiskCacheStrategy.NONE)                    .into(viewHolder.imageView);//显示的位置            //标记当前view            mLinearLayout.setTag(viewHolder);        } else {//可以重载则直接使用原来的view            mLinearLayout = (LinearLayout) view;            viewHolder = (ViewHolder) mLinearLayout.getTag();            //获取id            viewHolder.textTitle = mLinearLayout.findViewById(R.id.textTitle);            viewHolder.imageView = mLinearLayout.findViewById(R.id.imageView);            //设置数据            viewHolder.textTitle.setText(mList.get(i).getTextTitle());            //使用glide加载图片            Glide.with(mContext)                    .load(mList.get(i).getUrl()) //加载地址                    .placeholder(R.drawable.bitmap)//加载未完成时显示占位图                    .diskCacheStrategy(DiskCacheStrategy.NONE)                    .into(viewHolder.imageView);//显示的位置        }        return mLinearLayout;    }    //使用viewHolder缓存数据    static class ViewHolder {        TextView textTitle;        TextView url;        ImageView imageView;    }}

这个listview中的优化技巧我就不说了,重点是这个

 //使用glide加载图片            Glide.with(mContext)                    .load(mList.get(i).getUrl()) //加载地址                    .placeholder(R.drawable.bitmap)//加载未完成时显示占位图                    .diskCacheStrategy(DiskCacheStrategy.NONE)                    .into(viewHolder.imageView);//显示的位置

和dialog一样的链状表达,就是这么简单,明显,其实只要with load into 就ok了,但是为了提高用户体验和让glide可以展示gif,我们需要加上placeholder,这个是图片还未加载得时候,先放一张图片给用户看,告知图片未加载,我觉得这个比啥也不显示好;diskCacheStrategy(磁片缓存策略)属性是干啥得呢,因为gliede会为我们缓存图片(节省流量,wifi党无视),这样有好也有坏,如果是图片,自然是求之不得了,但是如果是gif呢,gif可是有好多帧的,等你一帧一帧的缓存的话再显示出来的话,已经好几分钟过去了,作为网页超过三秒无法显示就想点×的我,肯定是无法忍受的,那怎么办呢,不让你缓存不就得了,这个使用实在是太简单了

5、创建http请求类

这个我前面也讲过,之前做笑话数据得时候,我就使用asyncTask封装好了一个http请求类,只要是get得网络请求我们都可以在活动中进行复用,方便,省时,我就不多讲,注释也是写好得

package com.example1.ikecin.mypro.HttpHelper;import android.os.AsyncTask;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;/** * Created by wei on 2017/10/9. *///使用AsyncTask来对网络请求进行封装public class GetHttpData extends AsyncTask<String,Void,String> {    private String URL;    private TransmitHttpData transmitHttpData;    public GetHttpData(String URL, TransmitHttpData transmitHttpData)    {        //其他活动在调用此类时需要传递访问的网址        this.URL=URL;        this.transmitHttpData=transmitHttpData;    }    @Override    protected String doInBackground(String... params) {        try {            //传递网址            URL url=new URL(URL);            try {                //打开网络链接                HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();                //以GET的方式访问网络                httpURLConnection.setRequestMethod("GET");                //设置最长等待时间为5秒                httpURLConnection.setConnectTimeout(5000);                //获得网络返回的代码                int code=httpURLConnection.getResponseCode();                //code == 200表示网络请求成功                if (code==200)                {                    InputStream json = httpURLConnection.getInputStream();                    //将网页返回的数据解析成字符串数据                    BufferedReader reader=new BufferedReader(new InputStreamReader(json,"UTF-8"));                    StringBuilder response=new StringBuilder();                    String line;                    while ((line=reader.readLine())!=null)                    {                        response.append(line);                    }                    return response.toString();                }            } catch (IOException e) {                e.printStackTrace();            }        } catch (MalformedURLException e) {            e.printStackTrace();        }        return null;    }    @Override    protected void onPostExecute(String s) {        //将网络获得的数据通过接口传递给活动        transmitHttpData.GetData(s);    }}
值得注意得是这里面设置了一个回掉接口

package com.example1.ikecin.mypro.HttpHelper;/** * Created by wei on 2017/10/9. */public interface TransmitHttpData {    public void GetData(String data);}
这个接口得作用是获得http返回得数据,我们可以在活动中实现该接口,就可以获得数据,然后解析了

6、解析json数据

private void parseJson(String data) {    try {        JSONObject object = new JSONObject(data);        JSONArray result = object.optJSONArray("result");        for (int i = 0; i < result.length(); i++) {            bean = new Other_1_Bean();            JSONObject object1 = result.getJSONObject(i);            //设置标题            bean.setTextTitle(object1.optString("content"));            //获得图片的url            bean.setUrl(object1.optString("url"));            mList.add(bean);            //刷新数据            adapter.notifyDataSetChanged();        }    } catch (JSONException e) {        e.printStackTrace();    }}
这篇主要讲glide得使用,所以我就不对如何使用listview进行讲解了,前面也讲过

主代码:

package com.example1.ikecin.mypro;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.annotation.Nullable;import android.widget.ListView;import com.bumptech.glide.Glide;import com.bumptech.glide.load.engine.DiskCacheStrategy;import com.example1.ikecin.mypro.Adapter.Other_1_Adapter;import com.example1.ikecin.mypro.Adapter.Other_1_Bean;import com.example1.ikecin.mypro.HttpHelper.GetHttpData;import com.example1.ikecin.mypro.HttpHelper.TransmitHttpData;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;import butterknife.BindView;import butterknife.ButterKnife;/** * Created by awei on 2017/12/13. */public class Other_1_Activity extends Activity implements TransmitHttpData {    @BindView(R.id.listView)    ListView listView;    private Bitmap bitmap;    //网络请求类    private GetHttpData httpData;    //list    private List<Other_1_Bean> mList;    //适配器    private Other_1_Adapter adapter;    private Other_1_Bean bean;    private static final int UPDATE_IMAGE = 1;    private  String url;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_other_1);        ButterKnife.bind(this);        httpData= (GetHttpData) new GetHttpData("http://v.juhe.cn/joke/randJoke.php?key=60fbc4de5e9c94872a10268487583390&type=pic",this).execute();        initData();    }    private void initData() {        //初始数组        mList = new ArrayList<>();    }    @Override    public void GetData(String data) {        adapter = new Other_1_Adapter(this, mList);        parseJson(data);        //将adapter的初始化放在这里是为了确保mList有数据        listView.setAdapter(adapter);    }    private void parseJson(String data) {        try {            JSONObject object = new JSONObject(data);            JSONArray result = object.optJSONArray("result");            for (int i = 0; i < result.length(); i++) {                bean = new Other_1_Bean();                JSONObject object1 = result.getJSONObject(i);                //设置标题                bean.setTextTitle(object1.optString("content"));                //获得图片的url                bean.setUrl(object1.optString("url"));                mList.add(bean);                //刷新数据                adapter.notifyDataSetChanged();            }        } catch (JSONException e) {            e.printStackTrace();        }    }    /*do{                     new Thread(new Runnable() {                         @Override                         public void run() {                             try {                                 bitmap=getBitmap(url);                                 bean.setBitmap(bitmap);                             } catch (IOException e) {                                 e.printStackTrace();                             }                         }                     }).start();                 }while (bitmap!=null);*/    //得到bitmap    /*public static Bitmap getBitmap(String path) throws IOException {        URL url = new URL(path);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setConnectTimeout(5000);        conn.setRequestMethod("GET");        if (conn.getResponseCode() == 200) {            InputStream inputStream = conn.getInputStream();            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);            return bitmap;        }        return null;    }*/}
可以看到我在活动中注释起来得代码,这就是不用glide实现得方式,很麻烦,而且效果也不是很理想

反思与总结:

1、

//使用glide加载图片Glide.with(mContext)        .load(mList.get(i).getUrl()) //加载地址        .into(viewHolder.imageView);//显示的位置
这就是glide得核心用法,第一步,传个上下文对象,第二步,传个网址,第三步,图片放哪儿;给我得第一印象就是,简洁,明了;其他得属性自行百度

2、有人说会遇到图片错位得问题,目前我还没遇到过,如果有,我也会写一篇博客讲如何解决

3、我今天讲得只是知其然的做法,但是写程序不就是从  不知其然-->知其然-->知其所以然吗,不过很多人只到了第二步就没有进行下去了,不过,我想任何一个热爱编程的人,也都不会止步于第二步,掌握了第二步的人,就相当于车间里的工人,只会装配(之所以写这段话,是为了与诸君共勉,加油)

see you



原创粉丝点击