关于#kotlin#异步(大概)的问题:

题目描述
运行程序所有对话框都会弹出来

题目来源及自己的思路
我想做一个病历生成的程序,大体思路就是弹出对话框后根据选项的不同会有不同的分支,直到所有分支走完,病历完成。目前的问题是运行程序后不按我写的顺序弹出,查了一下好像是跟异步函数有关,有办法让对话框按我写的顺序弹出吗。还有个想增加的功能,就是在选错是可以撤回,并撤销已经生成的文字。
还有个问题,就是函数写太多,想把函数放在另一个文件,结果 MaterialDialog(android.this),这个this报错提示:'this' is not defined in this context


package com.example.medicarecord


import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItems

class MainActivity : AppCompatActivity() {
    private lateinit var resultTextView: TextView
    private lateinit var spinner: Spinner
    private lateinit var generateButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        resultTextView = findViewById(R.id.resultTextView)
        spinner = findViewById(R.id.spinner)
        generateButton = findViewById(R.id.generateButton)

        val options = listOf("发热", "咳嗽咳痰", "咯血","呼吸困难","头痛","胸痛","腹痛","关节痛","腰背痛","颈肩痛","心悸","水肿","恶心呕吐","呕血便血","腹泻","消瘦","黄疸","少尿无尿","多尿","尿频尿急尿痛","血尿","癫痫发作与惊厥","眩晕","意识障碍","皮肤黏膜出血") // 替换为你自己的选项列表

        // 创建适配器并设置选项列表
        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, options)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        spinner.adapter = adapter

        // 设置按钮点击监听器
        generateButton.setOnClickListener {
            val selectedOption = spinner.selectedItem.toString()
            // 根据选择的选项执行相应的函数
            when (selectedOption) {
                "发热" -> function1()
                "咳嗽咳痰" -> function2()
                "咯血" -> function3()
                "呼吸困难" -> function3()
                "头痛" -> function3()
                "胸痛" -> function3()
                "腹痛" -> function3()
                "关节痛" -> function3()
                "腰背痛" -> function3()
                "颈肩痛" -> function3()
                "心悸" -> function3()
                "水肿" -> function3()
                "恶心呕吐" -> function3()
                "呕血便血" -> function3()
                "腹泻" -> function3()
                "消瘦" -> function3()
                "黄疸" -> function3()
                "少尿无尿" -> function3()
                "多尿" -> function3()
                "尿频尿急尿痛" -> function3()
                "血尿" -> function3()
                "癫痫发作与惊厥" -> function3()
                "意识障碍" -> function3()
                "皮肤黏膜出血" -> function3()

            }
        }
    }

    private fun function1() {
        faRe()
    }

    private fun function2() {
        function2()
    }

    private fun function3() {
        function3()
    }

    private fun faRe() {
        val bansuizhengzhuang = mapOf(
            "体格检查" to "咽部粘膜未见异常,双侧扁桃体无肿大。双肺叩诊清音,呼吸规整,双肺呼吸音清晰,双侧肺未闻及干、湿性罗音,无胸膜摩擦音。",
            "其他不适" to "",
            "皮肤黏膜出血" to "",
            "皮疹" to "",
            "咯血" to "",
            "尿频、尿急、尿痛" to "",
            "腹痛腹泻" to "",
            "胸痛胸闷" to "",
            "头痛头晕" to "",
            "肌肉关节痛" to "",
            "咽痛" to "",
            "咳嗽咳痰" to "痰多色白易咯出"
        )
        val zhengzhuangtedian = mapOf(
            "热峰出现时间" to listOf("热峰出现时间在上午", "热峰出现时间在中午", "热峰出现时间在午后", "热峰出现时间在夜间"),
            "发热的特点" to listOf("呈持续性低热", "呈稽留热", "呈弛张热", "呈间歇热", "呈波状热", "呈回归热", "呈不规则热"),
            "发热程度" to listOf("发热,最高温度达?℃", "高热,最高温度达?℃", "低热,最高温度达?℃"),
            "起病诱因、病因" to listOf("xx前无明显诱因出现", "xx前感冒后出现", "xx前受凉后出现", "xx前创伤后出现"),
        )
        generateMedicalRecord("通用问诊:是否到过医院,做过哪些检查和治疗,治疗经过及药疗评价,饮食、睡眠、大小便及体重变化、传染病史,慢性病史,手术、外伤史,食物、药物过敏史,无吸烟、饮酒、药物等嗜好。")
        yiBanXuanXiang(bansuizhengzhuang)
        zhengZhuangTeDian(zhengzhuangtedian)
    }

    private fun zhengZhuangTeDian(sentenceOptions: Map<String, List<String>>) {
        // 循环遍历 sentenceOptions 字典
        for ((symptom, options) in sentenceOptions) {
            // 准备 showDialog 函数的参数
            val args = mutableListOf(symptom)
            args.addAll(options)

            // 使用可变参数调用 showDialog 函数
            showDialog(*args.toTypedArray())
        }
    }

    private fun showDialog(vararg options: String) {
        val items = options.toList()
        MaterialDialog(this)
            .title(text = items.firstOrNull())
            .listItems(
                items = items.drop(1),
                waitForPositiveButton = false
            ) { dialog, index, text ->
                // 将选择的文字追加到屏幕上
                generateMedicalRecord("$text,")
            }
            .show()
    }

    private fun yiBanXuanXiang(questions: Map<String, String>) {
        for ((questionText, zhuiJiaQuestion) in questions) {
            MaterialDialog(this)
                .title(text = questionText + "?")
                .listItems(
                    items = listOf("是", "否", "不详", "跳过"),
                    waitForPositiveButton = true
                ) { dialog, index, text ->
                    when (index) {
                        0 -> {
                            // 选择是,追加文字
                            generateMedicalRecord("有$questionText,")
                            zhuiJiaXuanXiang(zhuiJiaQuestion)
                        }
                        1 -> {
                            // 选择否,跳过追加文字
                            generateMedicalRecord("无$questionText,")
                        }
                        2 -> {
                            // 选择不详,跳过追加文字
                            generateMedicalRecord(questionText+"不详")
                        }
                        3 -> {
                            // 选择跳过,直接跳到下一个问题
                        }
                    }
                    dialog.dismiss()
                }
                .show()
        }
    }

    private fun zhuiJiaXuanXiang(zhuiJiaQuestion: String) {
        val combinedQuestionText = zhuiJiaQuestion
        if (combinedQuestionText.isNotEmpty()) {
            MaterialDialog(this)
                .title(text = combinedQuestionText)
                .listItems(
                    items = listOf("追加", "不追加"),
                    waitForPositiveButton = false
                ) { dialog, index, text ->
                    when (index) {
                        0 -> {
                            // 选择是,追加文字
                            generateMedicalRecord("$combinedQuestionText,")
                            // askVertigo()
                        }
                        1 -> {
                            // 选择否,跳过追加文字
                            // generateMedicalRecord("$combinedQuestionText,")
                            // askVertigo()
                        }
                    }
                    dialog.dismiss()
                }
                .show()
        }
    }

    private fun generateMedicalRecord(symptom: String) {
        resultTextView.append(symptom)
    }

    private fun showResult() {
        val result = resultTextView.text.toString()
    }
}

kotlin异步有挂起函数 但感觉不合适 感觉用队列 点击了dialog按钮后从队列里取出比较好

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7549941
  • 这篇博客也不错, 你可以看下Kotlin 学习笔记(三)函数的调用、中缀、解构、顶层扩展函数 使用
  • 除此之外, 这篇博客: Kotlin -特殊用法详解中的 2.对象字面量。这个特性将数字字面量,字符串字面量扩展到一般性对象中了。对应的场景是如果我们只需要“一个对象而已”,并不需要特殊超类型。典型的场景是在某些地方,比如函数内部,我们需要零碎地使用一些一次性的对象时,非常有用。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
      var user=object {
                var sex:Int=0
                var year:Int=1
            }
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
private fun XianZhengJian(){
    generateMedicalRecord("现症见:患者")
    showDropdownDialog("神清,","嗜睡,","昏睡,","昏迷,")
    showDropdownDialog("精神状态良好,","精神一般,","精神欠佳,","精神萎靡,")
    YiBanXuanXiang("发热恶寒","最高温度可达?℃,")
    YiBanXuanXiang("咳嗽咳痰","痰多色白易咯出")
    YiBanXuanXiang("头痛头晕")

}
如果想要按照问题顺序进行生成,第二个问题的弹窗应该写在第一个问题弹窗,选中item回调结果的地方。依次类推。就可以让问题有序的生成所谓的病历内容了。