当前位置: 首页 > 知识库问答 >
问题:

智能转换为“位图!”是不可能的,因为“textBitmap”是一个由变化的闭包捕获的局部变量

胡彭亮
2023-03-14

当我构建我的项目时,我得到了这个错误

下面是kotlin类代码

var textBitmap: Bitmap? = null
dynamicItem.dynamicText[imageKey]?.let { drawingText ->
            dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
drawTextCache[imageKey]?.let {
                    textBitmap = it
                } ?: kotlin.run {
                    textBitmap = Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888)
                    val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
                    val textCanvas = Canvas(textBitmap)
                    drawingTextPaint.isAntiAlias = true
                    val fontMetrics = drawingTextPaint.getFontMetrics();
                    val top = fontMetrics.top
                    val bottom = fontMetrics.bottom
                    val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
                    textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
                    drawTextCache.put(imageKey, textBitmap as Bitmap)
                }

我不知道如何解决它

共有2个答案

段干祺
2023-03-14

基本上静态编程语言不能智能地将text Bitmap转换为lambda中的非空位图。您可能在Canvas(text Bitmap调用中遇到错误,它不能接受空参数,并且编译器不能保证text Bitmap在那一刻不为空。

这是lambda引用外部vars的限制,可以更改-我认为这是因为lambda可能会在其他时间运行,因此无法保证外部变量发生了什么以及是否有其他东西可以修改它。我不知道细节,如果你愿意,这里有一些聊天。

但是,如果您所做的只是创建一个 textBitmap 变量并为其分配一些内容,那么修复非常简单:

// Assign it as a result of the expression - no need to create a var first and keep
// changing the value, no need for a temporary null value, it can just be a val
val textBitmap: Bitmap? =
    dynamicItem.dynamicText[imageKey]?.let { drawingText ->
        dynamicItem.dynamicTextPaint[imageKey]?.let { drawingTextPaint ->
            drawTextCache[imageKey]
            ?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).apply {
                    val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
                    val textCanvas = Canvas(this)
                    drawingTextPaint.isAntiAlias = true
                    val fontMetrics = drawingTextPaint.getFontMetrics();
                    val top = fontMetrics.top
                    val bottom = fontMetrics.bottom
                    val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
                    textCanvas.drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
                    drawTextCache.put(imageKey, this)
            }
        }
    }   

为了易读性,我建议将位图创建部分分解为自己的函数,就我个人而言,我会避免嵌套的lets(因为在什么情况下你会得到什么并不明显),但这是一种风格选择

夏晋
2023-03-14

而不是像这样做嵌套的<code>let

kotlin prettyprint-override">val drawingText = dynamicItem.dynamicText[imageKey] ?: return // or you could assign an empty string `?: "" `
val drawingTextPaint = dynamicItem.dynamicTextPaint[imageKey] ?: return
val textBitmap: Bitmap = drawTextCache[imageKey] ?: Bitmap.createBitmap(drawingBitmap.width, drawingBitmap.height, Bitmap.Config.ARGB_8888).applyCanvas {
   val drawRect = Rect(0, 0, drawingBitmap.width, drawingBitmap.height)
   val fontMetrics = drawingTextPaint.getFontMetrics()
   val top = fontMetrics.top
   val bottom = fontMetrics.bottom
   val baseLineY = drawRect.centerY() - top / 2 - bottom / 2
   drawingTextPaint.isAntiAlias = true
   drawText(drawingText, drawRect.centerX().toFloat(), baseLineY, drawingTextPaint);
}
drawTextCache.put(imageKey, textBitmap)
 类似资料: