需要单击两次以更新文本视图中的文本

Need to click twice to update text in text view

你好,我正在使用 ML Kit 进行屏幕手写识别的项目。

我面临的问题是我需要单击两次才能更新文本框中的文本。第一次单击时,它会识别文本,然后在第二次单击时,它会识别文本并进行更新。我是 Kotlin 的新手,我不知道为什么。

主要 activity :

StrokeManager.download()
recognize.setOnClickListener {

    StrokeManager.recognize(this)

    res()
    textview = findViewById(R.id.textView) as TextView
    textview.setText(res())

}

Strokemanger 对象文件:

fun recognize(context: Context) {
    val recognizer: DigitalInkRecognizer =
        DigitalInkRecognition.getClient(
            DigitalInkRecognizerOptions.builder(model).build()
        )


    val ink = inkBuilder.build()

    recognizer.recognize(ink)
        .addOnSuccessListener { result: RecognitionResult ->
            recogResult = result.candidates[0].text
        }
        .addOnFailureListener { e: Exception ->
            Log.e("StrokeManager", "Error during recognition: $e")
        }
}

fun res(): String? {
    var resultToText = recogResult

    return resultToText
}

下面是我的 git 项目的 link:

project link

recognizer.recognize(ink) 是一个异步调用。所以你必须等待它的结果,即成功或失败。因为我们必须在成功时显示结果,所以最好从 Success 调用 #res()。您可以按如下方式进行:

recognizer.recognize(ink)
        .addOnSuccessListener { result: RecognitionResult ->
        recogResult = result.candidates[0].text
        setRecResult()
 }
        .addOnFailureListener { e: Exception ->
        Log.e("StrokeManager", "Error during recognition: $e")
}



fun setRecResult(){
    runOnUiThread {
        textview = findViewById(R.id.textView) as TextView
        textview.setText(recogResult)  
    }
}

runOnUiThread 将阻止从后台线程访问 UI。

recognizer 异步工作。这意味着它不会在您调用 recognize 方法时立即 return 结果。当您调用 res() 时,OnSuccessListener 尚未被调用。

一种选择是修改 fun recognize(context: Context) 以接受另一个参数作为回调:

fun recognize(context: Context, callback: (String)->Unit) {
    val recognizer: DigitalInkRecognizer =
            DigitalInkRecognition.getClient(
                    DigitalInkRecognizerOptions.builder(model).build()
            )


    val ink = inkBuilder.build()

    recognizer.recognize(ink)
            .addOnSuccessListener { result: RecognitionResult ->
                    callback(result.candidates[0].text)
            }
            .addOnFailureListener { e: Exception ->
                    Log.e("StrokeManager", "Error during recognition: $e")
                    callback("Error during recognition")
            }
}

这就是“阅读”结果文本的更新版本的样子:

recognize.setOnClickListener {
    recognize.isClickable = false
    StrokeManager.recognize(this) { result ->
        recognize.isClickable = true
        textview = findViewById(R.id.textView) as TextView
        textview.setText(result)
    }
}

我使用 isClickable 属性 的 recognize 视图来防止在短时间内启动多个识别过程,尤其是在前一个过程尚未完成的情况下。