使用Glide在Android应用中加载网络图片

Oralie ·
更新时间:2024-11-11
· 521 次阅读

使用Glide在Android应用中加载网络图片

代码由于宽度比较小被换行了,看着很不整齐,其实很整齐,注释写得比较详细,比较多不容易阅读,可以先复制到ide或者Vscode里阅读

布局文件里只有一个imageview

动画资源文件可以不需要

Json文件放置的目录为

/rememberWords/internetPic/src/main/assets/test.json
如果没有assets文件夹的话就自己创建

gradle的设置

注意选择自己Module的build.gradle文件在这里插入图片描述

//这里是需要添加的代码段,注意是在dependencies添加,不是再创建一个dependencies dependencies { implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' compile 'org.apache.httpcomponents:httpcore:4.4.4' } //这里是需要直接添加在build.gradle文件中的 repositories { mavenCentral() google() }

MainActivity类
实现主要功能

package com.example.internetpic; import androidx.appcompat.app.AppCompatActivity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.Toast; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.request.RequestOptions; import org.apache.http.util.EncodingUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Random; import javax.xml.transform.Transformer; public class MainActivity extends AppCompatActivity { private ArrayList arrPicPath = new ArrayList();//list存储图片URL private String Str_json;//全局变量存储json文件转换来的字符串 private int index = 0;//List下标(索引) private float touchDownX,touchUpX;//按下、抬起时的X坐标 ImageView imageView;//这个就不要写了吧 Animation animation;//存储动画资源 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = findViewById(R.id.imageview);//ID获取image view animation = AnimationUtils.loadAnimation(this,R.anim.anim_alpha_in);//加载本地动画资源文件 imageView.setAnimation(animation);//给image view设置动画 doReadJson();//自定义方法,从本地读取Json文件 doParseJson();//自定义方法,解析Json文件 RequestOptions options = new RequestOptions();//实例化一个option对象,并设置属性 options.centerCrop()//设置居中 .transform(new dictionaryTransform())//调用transform,实例化dictionaryTransform类调用自定义方法BitmapMosaic实现打码 .placeholder(R.drawable.img_load)//设置加载时显示的图片(占位) .error(R.drawable.img_load)//失败时显示的图片 .fallback(R.drawable.img_load);//反馈图片 final RequestBuilder requestBuilder =//定义一个RequestBuilder对象 Glide.with(this)//实例化一个Glide对象 .asDrawable()//设置对象类型为Drawable .apply(options);//应用options的设置 final RequestBuilder requestBuilderwithout =//同上,但是这个对象不设置option,用以设置无打码的图片 Glide.with(this) //其实严谨点应该设置两个option .asDrawable(); requestBuilder.clone()//清除 .load(arrPicPath.get(index))//根据索引找到list中对应URL,load方法加载网络图片 .into(imageView);//把图片放进image view,注意:此时使用的是设置过option的对象,即打码的图片 // Glide.with(this).load("https://www.baidu.com/img/bd_logo1.png").into(imageView); imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {//为image view设置触摸监听事件 if (event.getAction() == MotionEvent.ACTION_DOWN) {//event.getAction()获取当前事件,利用常量判断该事件是否为按下事件 touchDownX = event.getX();//获取按下时的坐标,并存储 return false;//返回false表示按下事件没有被处理完,下面的监听事件才可以继续处理该按下事件 } else if (event.getAction() == MotionEvent.ACTION_UP) {//同上,判断是否抬起 touchUpX = event.getX();//获取抬起时坐标,储存 if (touchUpX - touchDownX > 50) {//判断按下抬起坐标间隔,并定义为一次从左到右滑动 Random r = new Random();//定义并实例化一个随机数对象 index = index == 0 ? arrPicPath.size() - 1 : r.nextInt(arrPicPath.size());//三位运算符,判断index是否等于0, // 若等于0则使index等于List的最后一个元素,若不等于0则使index等于生成的(0-list元素个数)一个随机数 //其实这一步逻辑上有错,因为一开始设置为有顺序的循环显示图片,所以需要判断左右滑动和List的下标防止越界 //改为随机后可直接删除左右滑动判断,和下标判断,直接随机数设置下标即可 requestBuilder.clone()//清除 .load(arrPicPath.get(index))//加载随机后的图片 .into(imageView);//设置进image view,同上,注意:此时依然设置的是打码图片 } else if (touchDownX - touchUpX > 50) {//同上,不再赘述 Random r = new Random(); index = index == arrPicPath.size() - 1 ? 0 : r.nextInt(arrPicPath.size()); requestBuilder.clone() .load(arrPicPath.get(index)) .into(imageView); } } return false;//注意!返回false表示抬起事件没有处理完,由于我下面的监听使用的是长按事件,所以上面两个是false还是true没有影响 //如果想使用单击事件(onClick)则按下事件要返回false } }); // Glide.with(this) // .load(R.drawable.img01) // .apply(options) // .into(imageView); imageView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) {//给image view设置长按事件 requestBuilderwithout.clone()//注意:此时使用的是没有设置option的对象,即加载的图片是无码的 .load(arrPicPath.get(index)) .into(imageView); return true;//返回true,表示长按事件处理完毕 } }); } /*读取Json*/ public void doReadJson(){ try { InputStream is = getResources().getAssets().open("test.json");//根据文件名打开json文件,并存入输入流对象 int length = is.available();//获取输入流字节长度 byte[] buffer = new byte[length];//定义一个字节数组作为缓冲,长度为输入流的长度 is.read(buffer);//将输入流中数据放进缓冲字节数组中 Str_json = EncodingUtils.getString(buffer,"utf-8");//把字节数组中的数据放入字符串中,这样就把json文件读取成了字符串 is.close();//切记,不要忘记关闭流 } catch (IOException e) { e.printStackTrace(); } } /*解析Json*/ public void doParseJson() { if (Str_json == null) {// 判断用户是否读取了Json文件 Toast.makeText(this, "请先读取Json文件!", Toast.LENGTH_SHORT).show();//没有就弹出提示 } else { try { JSONArray jsonArray = new JSONArray(Str_json);// 基于Str_json字符串创建Json对象数组 for (int i = 0; i < jsonArray.length(); i++) {// 遍历Json数组 JSONObject jsonObject = jsonArray.getJSONObject(i);// 通过下标获取json数组元素——Json对象 // 对Json对象按键取值,其实我只需要image的网址就行了,也不需要组成对象2333,但是这只是个demo,组成对象是为了供后面使用 int id = jsonObject.getInt("id"); String word = jsonObject.getString("word"); String explain = jsonObject.getString("explain"); String sound = jsonObject.getString("sound"); String image = "https://fox.ftqq.com/"+jsonObject.getString("image"); Word wordObject = new Word(id, word, explain, sound, image);// 组成Word对象 arrPicPath.add(wordObject.getImage());//获取对象中的image的值,并添加到List中 } } catch (JSONException e) { e.printStackTrace(); } } } }

dictionaryTransform类
用来实现打码功能
其中的打码方法是在一篇文章里看到的,找不到来源了,原作者如果看到的话可以加上您的链接嗷

package com.example.internetpic; import android.graphics.Bitmap; import android.graphics.Color; import androidx.annotation.NonNull; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; import java.security.MessageDigest; public class dictionaryTransform extends BitmapTransformation { @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { return BitmapMosaic(toTransform,40); } @Override public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { } public static Bitmap BitmapMosaic(Bitmap bitmap, int BLOCK_SIZE) { if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0 || bitmap.isRecycled()) { return null; } int mBitmapWidth = bitmap.getWidth(); int mBitmapHeight = bitmap.getHeight(); Bitmap mBitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);//创建画布 int row = mBitmapWidth / BLOCK_SIZE;// 获得列的切线 int col = mBitmapHeight / BLOCK_SIZE;// 获得行的切线 int[] block = new int[BLOCK_SIZE * BLOCK_SIZE]; for (int i = 0; i <=row; i++) { for (int j =0; j <= col; j++) { int length = block.length; int flag = 0;// 是否到边界标志 if (i == row && j != col) { length = (mBitmapWidth - i * BLOCK_SIZE) * BLOCK_SIZE; if (length == 0) { break;// 边界外已经没有像素 } bitmap.getPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, mBitmapWidth - i * BLOCK_SIZE, BLOCK_SIZE); flag = 1; } else if (i != row && j == col) { length = (mBitmapHeight - j * BLOCK_SIZE) * BLOCK_SIZE; if (length == 0) { break;// 边界外已经没有像素 } bitmap.getPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, mBitmapHeight - j * BLOCK_SIZE); flag = 2; } else if (i == row && j == col) { length = (mBitmapWidth - i * BLOCK_SIZE) * (mBitmapHeight - j * BLOCK_SIZE); if (length == 0) { break;// 边界外已经没有像素 } bitmap.getPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, mBitmapWidth - i * BLOCK_SIZE, mBitmapHeight - j * BLOCK_SIZE); flag = 3; } else { bitmap.getPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);//取出像素数组 } int r = 0, g = 0, b = 0, a = 0; for (int k = 0; k < length; k++) { r += Color.red(block[k]); g += Color.green(block[k]); b += Color.blue(block[k]); a += Color.alpha(block[k]); } int color = Color.argb(a / length, r / length, g / length, b / length);//求块内所有颜色的平均值 for (int k = 0; k < length; k++) { block[k] = color; } if (flag == 1) { mBitmap.setPixels(block, 0, mBitmapWidth - i * BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, mBitmapWidth - i * BLOCK_SIZE, BLOCK_SIZE); } else if (flag == 2) { mBitmap.setPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, mBitmapHeight - j * BLOCK_SIZE); } else if (flag == 3) { mBitmap.setPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, mBitmapWidth - i * BLOCK_SIZE, mBitmapHeight - j * BLOCK_SIZE); } else { mBitmap.setPixels(block, 0, BLOCK_SIZE, i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } } //并没有回收传进来的bitmap 原因是JAVA传值默认是引用,如果回收了之后,其他地方用到bitmap的位置可能报NULL指针异常,请根据实际情况决定是否回收. return mBitmap; } }
作者:璃火烨烨



网络图 图片 glide Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号