使用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
- 使用glide图片加载框架将网络图片展示并在listview中
- Glide网络加载图片框架使用教程
- 在GridView或者ListView的Adapter中使用Glide加载图片,图片被拉伸问题
- listview中glide加载网络图片跳跃问题
- picasso glide 图片加载并缓存的框架使用
- Android ZoomImageView手势缩放拖动图片,并将Glide加载的网络图片保存到本地。
- 图片加载框架Glide
- 图片加载框架,Glide
- 加载图片框架Glide
- Glide图片加载框架
- Android中图片加载框架Glide的使用
- Glide--在listview中加载高度不固定图片,加载刷新图片跳动解决
- github图片加载框架glide使用介绍
- android glide 图片加载框架使用
- 图片加载框架Glide使用教程
- Android图片加载Glide框架使用详解
- 图片加载框架Glide使用详解
- Android图片加载Glide框架使用详解
- CSDN等级
- Markdown系列(7)- Markdown中插入图片的三个技巧
- 技术分享连载(八十八)
- Linux 学习--GNU nano编辑器的使用
- webpack管理Vue项目--组件和路由引入
- 使用glide图片加载框架将网络图片展示并在listview中
- leetcode_572. Subtree of Another Tree ? 待解决
- 《极客与团队》【PDF】下载
- 微信运动过气了吗?
- python学习之日志模块logging
- webApplication的理解以及对应的配置解读
- 「敏捷开发」适合什么样的团队?
- 抽象类 和 接口
- 使用logback写日志