当前位置: 首页 > news >正文

Android Glide in RecyclerView,only load visible item when page return,Kotlin

Android Glide in RecyclerView,only load visible item when page return,Kotlin

base on this article:

Android Glide preload RecyclerView切入后台不可见再切换可见只加载当前视野可见区域item图片,Kotlin_zhangphil的博客-CSDN博客【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/132592405

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

plugins {id("org.jetbrains.kotlin.kapt")
}
    implementation("com.github.bumptech.glide:glide:4.16.0")kapt("com.github.bumptech.glide:compiler:4.16.0")

import android.content.Context
import android.graphics.Bitmap
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Targetconst val PHOTO_SIZE = 150class MainActivity : AppCompatActivity() {private val TAG = "Glide Load"private var mItems = ArrayList<MyData>()private var mLayoutManager: GridLayoutManager? = nullprivate var mAdapter: MyAdapter? = nullprivate var mGlideLoad: GlideLoad? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.recycler_view)init()}//当按了home键后,再次调出app,会进入onRestartoverride fun onRestart() {super.onRestart()Log.d(TAG, "onRestart")mGlideLoad?.clear()}override fun onStop() {super.onStop()Log.d(TAG,"onStop")}private fun init() {val spanCount = 8val rv = findViewById<RecyclerView>(R.id.recycler_view)mLayoutManager = GridLayoutManager(this, spanCount)rv.layoutManager = mLayoutManagermAdapter = MyAdapter(this)rv.adapter = mAdaptermItems = readAllImage(applicationContext)mAdapter?.onChange(mItems)mGlideLoad = GlideLoad(this, rv)}fun loadItem(holder: MyVH, position: Int) {val target: Target<*> = GlideApp.with(holder.itemView.context).asBitmap().load(mItems[position].path).centerCrop().addListener(object : RequestListener<Bitmap> {override fun onLoadFailed(e: GlideException?,model: Any?,target: Target<Bitmap>,isFirstResource: Boolean): Boolean {mGlideLoad?.setLoadStatus(position, GlideLoad.NONE, null)return false}override fun onResourceReady(resource: Bitmap,model: Any,target: Target<Bitmap>?,dataSource: DataSource,isFirstResource: Boolean): Boolean {holder.image.setImageBitmap(resource)mGlideLoad?.setLoadStatus(position, GlideLoad.NONE, null)// 特别注意此处返回是true,而不能是false。// 因为如果返回false,当按home键把app切入后台后,再按app图标调出app切换到前台可见,反复切换,// 会造成Bitmap未回收的崩溃。return true}}).preload(PHOTO_SIZE,PHOTO_SIZE)mGlideLoad?.setLoadStatus(position, GlideLoad.LOAD, target)}inner class MyAdapter(private val context: Context) : RecyclerView.Adapter<MyVH>() {private var items = ArrayList<MyData>()fun onChange(items: ArrayList<MyData>) {this.items = itemsnotifyDataSetChanged()}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyVH {val v = LayoutInflater.from(context).inflate(R.layout.item, parent, false)val params = v.layoutParamsparams.width = PHOTO_SIZEparams.height = PHOTO_SIZEreturn MyVH(v)}override fun onBindViewHolder(holder: MyVH, position: Int) {loadItem(holder, position)holder.text.text = "$position"}override fun getItemCount(): Int {return items.size}}private fun readAllImage(context: Context): ArrayList<MyData> {val photos = ArrayList<MyData>()//读取手机图片val cursor = context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null)while (cursor!!.moveToNext()) {//图片路径 urival path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))//图片名称//val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))//图片大小//val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))photos.add(MyData(path))}cursor.close()return photos}
}class MyVH(itemView: View) : RecyclerView.ViewHolder(itemView) {var image: AppCompatImageViewvar text: TextViewinit {image = itemView.findViewById(R.id.image)text = itemView.findViewById(R.id.text)}
}class MyData(var path: String)

<?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=".MainActivity"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"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="wrap_content"android:layout_height="wrap_content"android:padding="1px"><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerCrop"android:src="@drawable/ic_launcher_background" /><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="@android:color/holo_green_light"android:paddingLeft="1dp"android:paddingRight="1dp"android:text="-.-"android:textColor="@android:color/holo_red_dark"android:textSize="5dp" />
</RelativeLayout>

import android.content.Context
import android.util.Log
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.request.target.Target
import java.lang.ref.WeakReferenceclass GlideLoad {private val TAG = "Glide Load"companion object {const val NONE: Int = 0const val LOAD: Int = 1}private var mLayoutManager: GridLayoutManager? = nullprivate var mRecyclerView: RecyclerView? = nullprivate var mVisibleItemPosition: IntArray? = nullprivate var mContext: Context? = nullprivate var mStatusItems: ArrayList<Status>? = ArrayList()constructor(ctx: Context?, rv: RecyclerView?) {mContext = ctxmRecyclerView = rvrepeat(mRecyclerView?.adapter?.itemCount!!) {mStatusItems?.add(Status())}mLayoutManager = mRecyclerView?.layoutManager as? GridLayoutManagermRecyclerView?.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {super.onScrolled(recyclerView, dx, dy)mVisibleItemPosition = getVisibleItemPosition()}})}fun setLoadStatus(pos: Int, status: Int, target: Target<*>?) {mStatusItems!![pos].position = posmStatusItems!![pos].status = statusif (target != null) {mStatusItems!![pos].targetRef = WeakReference(target)} else {mStatusItems!![pos].targetRef = null}}fun clear() {Log.d(TAG, "可见区域 ${mVisibleItemPosition!![0]}->${mVisibleItemPosition!![1]}")for (i in 0 until mStatusItems!!.size) {if (i !in mVisibleItemPosition!![0]..mVisibleItemPosition!![1]) {if (mStatusItems!![i].status == LOAD) {mStatusItems!![i].targetRef?.get()?.let {GlideApp.with(mContext!!).clear(it)}mStatusItems!![i].status = NONEmStatusItems!![i].targetRef = null}}}}private fun getVisibleItemPosition(): IntArray {val first = mLayoutManager?.findFirstVisibleItemPosition()val last = mLayoutManager?.findLastVisibleItemPosition()return intArrayOf(first!!, last!!)}class Status {var targetRef: WeakReference<Target<*>>? = nullvar status = NONEvar position = 0}
}

import android.content.Context
import android.util.Log
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule@GlideModule
class MyModule : AppGlideModule() {override fun applyOptions(context: Context, builder: GlideBuilder) {builder.setLogLevel(Log.DEBUG)}override fun isManifestParsingEnabled(): Boolean {return false}
}

http://www.lryc.cn/news/156181.html

相关文章:

  • 【SCI征稿】3个月左右录用!计算机信息技术等领域均可,如机器学习、遥感技术、人工智能、物联网、人工神经网络、数据挖掘、图像处理
  • Golang 中的 crypto/ecdh 包详解
  • 系统学习live555
  • Linux下的系统编程——进程的执行与回收(八)
  • 第十九章 ObjectScript - 执行例程
  • Podman安装与使用
  • C++ 嵌套循环
  • 锁( ReentrantLock,Synchronized)
  • 主频计算-架构真题(二十三)
  • docker安装redis实操记录
  • MobaXterm 突破14个session限制
  • 使用Redisson实现高并发抢红包
  • 【网络编程】TCP/IP协议(互联网的基石)
  • 【VS Code插件开发】自定义侧边栏、视图(六)
  • lv3 嵌入式开发-8 linux shell脚本函数
  • 国际版阿里云腾讯云免费开户:服务器怎样转移
  • 区块链实验室(20) - FISCO控制台连接到指定的节点
  • 网络渗透day10-工具和技术
  • SSE 和 WebSocket 应用
  • mac帧 arp
  • java面试题-Redis相关面试题
  • 你用过 Maven Shade 插件吗?
  • Android 后台启动Activity适配
  • 使用element-ui中的el-table回显已选中数据时toggleRowSelection报错
  • Ubuntu18.04系统下通过ROS控制Kinova真实机械臂-多种实现方式
  • 聊聊如何玩转spring-boot-admin
  • rocky(centos) 安装redis,并设置开机自启动
  • Flask狼书笔记 | 06_电子邮件
  • ChatGPT追祖寻宗:GPT-1论文要点解读
  • 回归拟合 | 灰狼算法优化核极限学习机(GWO-KELM)MATLAB实现