为点击侦听器拆分大型方法的最佳方法

Best way to split a large method for click listener

重建我的项目后,我收到一条错误消息,指出我的一个方法太大,然后它将我定向到点击监听器。有谁知道拆分方法或分解方法的好方法?老实说,当所有连接的字符串(RecyclerView 和数组中的 500 多个)都与同一项目相关时,我不知道推荐的方法。

Method too large

e: java.lang.IllegalStateException: Backend Internal error: Exception during code generation

        ibMap.setOnClickListener {
            when {
                tvTitle.text.toString() == "029" -> {
                    when {
                        isAppInstalled -> { // Intent to launch Google Maps if the standard package is already installed

                            val gmmIntentUri =
                                Uri.parse("geo:0,0?q=Cardiff, United Kingdom")

                            val mapIntent =
                                Intent(Intent.ACTION_VIEW, gmmIntentUri)

                            mapIntent.setPackage("com.google.android.apps.maps")

                            // Attempt to start an activity that can handle the Intent
                            mCtx.startActivity(mapIntent)
                        }
                        isLiteAppInstalled -> { // Intent to launch Google Maps Go if the lite package is already installed

                            val gmmIntentUri =
                                Uri.parse("geo:0,0?q=Cardiff, United Kingdom")

                            val mapIntent =
                                Intent(Intent.ACTION_VIEW, gmmIntentUri)

                            mapIntent.setPackage("com.google.android.apps.mapslite")

                            mCtx.startActivity(mapIntent)
                        }
                        else -> { // Intent to launch Google Maps in web browser if neither of the above apps are installed

                            val str =
                                "https://www.google.com/maps/place/Cardiff,+United+Kingdom/"

                            // Attempt to start an activity that can handle the Intent
                            mCtx.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str)))
                        }
                    }
                }

               // 500 more strings
            }

即使在这个小样本中,您也有很多重复代码。一般来说,您应该避免复制粘贴代码块,而是将它们提取为单独的方法。首先将其添加到您的 RecyclerView 适配器中或您的 onclick 可以到达的任何地方:

fun launchMapIntent(locationName: String) {
    // determine package to open
    val mapPkg = when {
        isAppInstalled -> "com.google.android.apps.maps"
        isLiteAppInstalled -> "com.google.android.apps.mapslite"
        else -> null
    }
    val mapIntent = if(mapPkg != null) {
        // open app
        val gmmIntentUri = Uri.parse("geo:0,0?q=$locationName")
        Intent(Intent.ACTION_VIEW, gmmIntentUri).setPackage(mapPkg)
    } else {
        // fallback to browser
        val encLoc = Uri.encode(locationName)
        val str = "https://www.google.com/maps/place/$encLoc/"
        Intent(Intent.ACTION_VIEW, Uri.parse(str))
    }
    mCtx.startActivity(mapIntent)
}

然后您可以从您的 onclick 侦听器中清除重复代码:

ibMap.setOnClickListener {
    when(tvTitle.text.toString()) {
        "029" -> launchMapIntent("Cardiff, United Kingdom")
        "030" -> launchMapIntent("other location...")
        // other cases
    }
}

或者,如果您的所有案例都打开地图:

ibMap.setOnClickListener {
    val locationName = when(tvTitle.text.toString()) {
        "029" -> "Cardiff, United Kingdom"
        "030" -> "other location..."
        // other cases
    }
    launchMapIntent(locationName)
}

您可以通过 Map<Int, String> 以数字作为键、位置名称作为值而不是使用巨大的开关或以某种方式将它们保存在数据库等中来进一步优化