提问人:flowerProgrammer 提问时间:10/25/2023 最后编辑:flowerProgrammer 更新时间:10/25/2023 访问量:42
将 ListView 转换为位图
Converting a ListView to Bitmap
问:
我想将 ListView 转换为位图图像。 以下代码工作正常,但列表长于屏幕的情况除外。我设法使画布达到所需的大小,但它仍然只显示适合屏幕的元素,而另一个区域只是白色:
fun getBitmapFromView(view: ListView): Bitmap {
val listAdapter = view.adapter
var totalHeight = listView.paddingTop + listView.paddingBottom
val desiredWidth = MeasureSpec.makeMeasureSpec(listView.width, MeasureSpec.AT_MOST)
for (i in 0 until listAdapter.getCount()) {
val listItem: View = listAdapter.getView(i, null, listView)
if (listItem != null) {
listItem.layoutParams =
RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
)
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED)
totalHeight += listItem.measuredHeight
}
}
val bitmap = Bitmap.createBitmap(view.width, totalHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap )
val bgDrawable = view.background
if (bgDrawable != null) bgDrawable.draw(canvas) else canvas.drawColor(Color.WHITE)
view.draw(canvas)
return bitmap
}
我怎样才能修复它以包含整个列表?
答:
-1赞
flowerProgrammer
10/25/2023
#1
我设法通过调整 Kotlin 中 ListView 的 RecyclerView 全长屏幕截图中的代码来使其工作。感谢您的帮助。
fun getBitmapFromView(listView: ListView): Bitmap? {
val adapter: ListAdapter = listView.adapter
var bigBitmap: Bitmap? = null
if (adapter != null) {
val size = adapter.count
var height = 0
val paint = Paint()
var iHeight = 0
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
// Use 1/8th of the available memory for this memory cache.
val cacheSize = maxMemory / 8
val bitmapCache = LruCache<String, Bitmap>(cacheSize)
for (i in 0 until size) {
val itemView = adapter.getView(i, null, listView) as View
itemView.measure(
View.MeasureSpec.makeMeasureSpec(listView.width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
itemView.layout(0, 0, itemView.measuredWidth, itemView.measuredHeight)
itemView.isDrawingCacheEnabled = true
itemView.buildDrawingCache()
val drawingCache = itemView.drawingCache
if (drawingCache != null) {
bitmapCache.put(i.toString(), drawingCache)
}
height += itemView.measuredHeight
}
bigBitmap = Bitmap.createBitmap(listView.width, height, Bitmap.Config.ARGB_8888)
val bigCanvas = Canvas(bigBitmap)
bigCanvas.drawColor(Color.WHITE)
for (i in 0 until size) {
val bitmap = bitmapCache.get(i.toString())
bigCanvas.drawBitmap(bitmap, 0f, iHeight.toFloat(), paint)
iHeight += bitmap?.height ?: 0
bitmap?.recycle()
}
}
return bigBitmap
}
0赞
Marcin Mrugas
10/25/2023
#2
fun getBitmapFromView(listView: ListView): Bitmap {
val listAdapter = listView.adapter
var totalHeight = listView.paddingTop + listView.paddingBottom
val desiredWidth = listView.width
for (i in 0 until listAdapter.count) {
val childView = listAdapter.getView(i, null, listView)
val widthMeasureSpec = MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.EXACTLY);
childView.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED)
childView.layout(0, 0, childView.measuredWidth, childView.measuredHeight)
totalHeight += childView.measuredHeight
}
val bitmap = Bitmap.createBitmap(listView.width, totalHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
var topDrawDistance = 0
for (i in 0 until listAdapter.count) {
val childView = listAdapter.getView(i, null, listView)
val widthMeasureSpec = MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.EXACTLY);
childView.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED)
val childBitmap = Bitmap.createBitmap(childView.measuredWidth, childView.measuredHeight, Bitmap.Config.ARGB_8888)
val childCanvas = Canvas(childBitmap)
childView.layout(0, 0, childView.measuredWidth, childView.measuredHeight)
childView.draw(childCanvas)
canvas.drawBitmap(
childBitmap,
Rect(0, 0, childView.measuredWidth, childView.measuredHeight),
Rect(0, topDrawDistance, childView.measuredWidth, topDrawDistance + childView.measuredHeight),
Paint()
)
topDrawDistance += childView.measuredHeight
}
return bitmap
}
注意事项:
- 不再推荐使用 ListView,RecyclerView 是用于创建列表的较新版本。
- 如果要绘制整个列表,则必须单独绘制每个项目,因为屏幕下方的项目尚未呈现。
- 你需要调用函数
layout()
- 父视图的绘图背景是无用的,因为它的高度等于屏幕高度。
- 在适配器中迭代项目时,请使用循环变量而不是静态变量
i
0
评论
Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)