Лучший способ разделить большой метод для прослушивателя кликов - PullRequest
0 голосов
/ 05 января 2020

После перестройки моего проекта я получаю сообщение об ошибке, в котором говорится, что один из моих методов слишком велик, и затем он направляет меня к прослушивателю щелчков. Кто-нибудь знает хороший способ разбить метод или разбить его? Честно говоря, я понятия не имею о рекомендованном способе сделать это, когда все связанные строки (500+ в пределах RecyclerView и массива) связаны с одним и тем же элементом.

Слишком большой метод

и

e: java .lang.IllegalStateException: Backend Внутренняя ошибка: исключение при генерации кода

        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
            }

1 Ответ

2 голосов
/ 06 января 2020

У вас много повторяющегося кода даже в этом небольшом примере. В общем, вы должны избегать копирования блоков кода и вместо этого извлекать их как отдельный метод. Сначала добавьте его в свой адаптер 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> с числами в качестве ключей и именами местоположений в качестве значений вместо огромного переключателя или каким-то образом удерживая их в базе данных и т. д. c

...