Android Glide自定义AppCompatImageView切分成若干小格子,每个小格子onDraw绘制Bitmap,Kotlin(1)

本文主要是介绍Android Glide自定义AppCompatImageView切分成若干小格子,每个小格子onDraw绘制Bitmap,Kotlin(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android Glide自定义AppCompatImageView切分成若干小格子,每个小格子onDraw绘制Bitmap,Kotlin(1)

 

垂直方向的RecyclerView,每行一个AppCompatImageView,每个AppCompatImageView被均匀切割成n个小格子, 每个小格子通过Glide加载出来Bitmap,然后onDraw绘制整行。

 

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

 

implementation("com.github.bumptech.glide:glide:4.16.0")

 

import android.content.Context
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContextclass MainActivity : AppCompatActivity() {companion object {const val VIEW_TYPE = 0const val TAG = "fly/MainActivity"}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val rv = findViewById<RecyclerView>(R.id.recycler_view)val layoutManager = LinearLayoutManager(this)layoutManager.orientation = LinearLayoutManager.VERTICALrv.layoutManager = layoutManagerval adapter = MyAdapter()rv.adapter = adapterlifecycleScope.launch(Dispatchers.IO) {val items = readAllImage(this@MainActivity)items.reverse()val data = sliceDataList(items)withContext(Dispatchers.Main) {adapter.dataChanged(data)}}}private fun sliceDataList(data: ArrayList<MyData>): ArrayList<ArrayList<MyData>> {var k: Intval lists = ArrayList<ArrayList<MyData>>()for (i in data.indices step BatchBitmapView.ROW_SIZE) {val temp = ArrayList<MyData>()k = 0for (j in 0 until BatchBitmapView.ROW_SIZE) {k = i + jif (k >= data.size) {break}temp.add(data[k])}lists.add(temp)}return lists}class MyAdapter : RecyclerView.Adapter<MyVH>() {private var items = ArrayList<ArrayList<MyData>>()fun dataChanged(items: ArrayList<ArrayList<MyData>>) {this.items = itemsnotifyDataSetChanged()}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyVH {Log.d(TAG, "onCreateViewHolder")val view = BatchBitmapView(parent.context)return MyVH(view)}override fun getItemCount(): Int {return items.size}override fun getItemViewType(position: Int): Int {return VIEW_TYPE}override fun onBindViewHolder(holder: MyVH, position: Int) {Log.d(TAG, "onBindViewHolder $position")val biv = (holder.itemView as? BatchBitmapView)biv?.setRowBitmapData(items[position], position)}}class MyVH(itemView: BatchBitmapView) : RecyclerView.ViewHolder(itemView) {}class MyData(var path: String, var index: Int)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)var index = 0while (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, index++))}cursor.close()return photos}
}

 

 

 

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.Log
import androidx.appcompat.widget.AppCompatImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transitionclass BatchBitmapView @JvmOverloads constructor(context: Context,attributeSet: AttributeSet? = null,defStyleAttr: Int = 0
) : AppCompatImageView(context, attributeSet, defStyleAttr) {private val mData = mutableListOf<DataBean>()private val mScreenWidth = resources.displayMetrics.widthPixelsprivate val mTargets = mutableListOf<CustomTarget<Bitmap>>()companion object {const val TAG = "fly/BatchBitmapView"const val ROW_SIZE = 16 //一行多少个bitmapconst val IMAGE_SIZE = 80 //每个小格子图片的尺寸}fun setRowBitmapData(rows: ArrayList<MainActivity.MyData>?, position: Int) {Log.d(TAG, "setRowBitmapData $position")mData.clear()Log.d(TAG, "mTargets.size=${mTargets.size}")mTargets.forEach {Glide.with(context).clear(it) //如果不清楚,会发生有些图错放位置。}mTargets.clear() //mTargets上下滑动列表会越来越大,清空,一直保持ROW_SIZE.rows?.forEachIndexed { index, myData ->val target = object : CustomTarget<Bitmap>() {override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {val bean = DataBean(resource)mData.add(bean)postInvalidate()}override fun onLoadCleared(placeholder: Drawable?) {}}Glide.with(context).asBitmap().centerCrop().override(IMAGE_SIZE).load(myData.path).into(target)mTargets.add(target)}}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {super.onMeasure(widthMeasureSpec, heightMeasureSpec)setMeasuredDimension(mScreenWidth, IMAGE_SIZE)}override fun onDraw(canvas: Canvas) {super.onDraw(canvas)mData.forEachIndexed { index, dataBean ->canvas.save()var left = (mScreenWidth / ROW_SIZE) * indexcanvas.drawBitmap(dataBean.bitmap, left.toFloat(), 0f, null)canvas.restore()}}data class DataBean(val bitmap: Bitmap)
}

上面每一行加载16个bitmap绘图,速度很快,因为是canvas直接绘图。但是,如果使用下文的方式:

Android LinearLayout dynamic add child ImageView,Glide load,kotlin_zhangphil的博客-CSDN博客文章浏览阅读645次。【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/132080406即每一行先初始化一个水平的线性布局,然后逐个添加16个ImageView,对比发现明显卡顿,因为是以ViewGroup的方式布局摆放子view形成View。

 

 

 

Android Glide CustomTarget ,kotlin-CSDN博客文章浏览阅读1.4k次。【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/131661819

 

这篇关于Android Glide自定义AppCompatImageView切分成若干小格子,每个小格子onDraw绘制Bitmap,Kotlin(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/476358

相关文章

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Kotlin 协程之Channel的概念和基本使用详解

《Kotlin协程之Channel的概念和基本使用详解》文章介绍协程在复杂场景中使用Channel进行数据传递与控制,涵盖创建参数、缓冲策略、操作方式及异常处理,适用于持续数据流、多协程协作等,需注... 目录前言launch / async 适合的场景Channel 的概念和基本使用概念Channel 的

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

SpringBoot AspectJ切面配合自定义注解实现权限校验的示例详解

《SpringBootAspectJ切面配合自定义注解实现权限校验的示例详解》本文章介绍了如何通过创建自定义的权限校验注解,配合AspectJ切面拦截注解实现权限校验,本文结合实例代码给大家介绍的非... 目录1. 创建权限校验注解2. 创建ASPectJ切面拦截注解校验权限3. 用法示例A. 参考文章本文

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Kotlin 枚举类使用举例

《Kotlin枚举类使用举例》枚举类(EnumClasses)是Kotlin中用于定义固定集合值的特殊类,它表示一组命名的常量,每个枚举常量都是该类的单例实例,接下来通过本文给大家介绍Kotl... 目录一、编程枚举类核心概念二、基础语法与特性1. 基本定义2. 带参数的枚举3. 实现接口4. 内置属性三、