Как упростить все возможные комбинации этих параметров запроса в Kotlin? Шаблон Строителя? - PullRequest
0 голосов
/ 09 июля 2020

Я создаю приложение Android с Kotlin, которое использует различные API-интерфейсы NYTimes для получения различных данных новостей. Здесь у меня есть экран поиска, где я хочу, чтобы пользователь мог ввести поисковый запрос (т.е. Япония ") и снимите любой флажок, и они даже смогут добавить дату начала или окончания для уточнения поиска:

enter image description here

Typing something in the search query and checking off at least one box are the only requirements, everything else will be mandatory. And once they hit "Search", it will pass the data they entered to a second activity which will use the data to put together an api call, make the api call, and populate a recyclerview , like so:

введите описание изображения здесь

Теперь вот моя проблема ... У меня есть кнопка ПОИСК, отправляющая данные только в том случае, если поисковый запрос был введен, и если флажок путешествия был установлен, и, как вы можете представить, есть ТОННА комбинаций ... Я не знаю, как я могу пропустить все эти комбинации и сделать каждый вызов API соответственно, не имея чрезвычайно длинного блока If / Else, который займет вечность ... Используя Kotlin, должен быть более эффективный способ, правда?

Вот моя активность поиска:

class SearchActivity : AppCompatActivity() {

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

        search_query_edittext.getBackground().clearColorFilter();


        actionBar?.setDisplayHomeAsUpEnabled(true)
        Enter_Begin_Date.setPaintFlags(Enter_Begin_Date.getPaintFlags())
        Enter_End_Date.setPaintFlags(Enter_End_Date.getPaintFlags())

        // Calendar
        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val day = c.get(Calendar.DAY_OF_MONTH)

        // TextView Clicked to show Date Picker Dialog
        Enter_Begin_Date.setOnClickListener {
            val dpd = DatePickerDialog(
                this,
                DatePickerDialog.OnDateSetListener { view, Year, Month, Day ->
                    // set to textView
                    if (Day < 10 && Month < 10) {
                        Enter_Begin_Date.text =
                            "0" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
                    } else if (Day < 10 && Month >= 10) {
                        Enter_Begin_Date.text = "0" + Day + "/" + Month.toInt().plus(1) + "/" + Year
                    } else if (Day >= 10 && Month < 10) {
                        Enter_Begin_Date.text = "" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
                    }

                },
                year,
                month,
                day
            )
            // show dialog
            dpd.show()
        }

        Enter_End_Date.setOnClickListener {
            val dpd = DatePickerDialog(
                this,
                DatePickerDialog.OnDateSetListener { view, Year, Month, Day ->
                    // set to textView
                    if (Day < 10 && Month < 10) {
                        Enter_End_Date.text = "0" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
                    } else if (Day < 10 && Month >= 10) {
                        Enter_End_Date.text = "0" + Day + "/" + Month.toInt().plus(1) + "/" + Year
                    } else if (Day >= 10 && Month < 10) {
                        Enter_End_Date.text = "" + Day + "/0" + Month.toInt().plus(1) + "/" + Year
                    }

                },
                year,
                month,
                day
            )
            // show dialog
            dpd.show()
        }

        searchButton.setOnClickListener {
            if ((search_query_edittext.text.isNotEmpty()
                        && Enter_Begin_Date.text.isEmpty()
                        && Enter_End_Date.text.isEmpty()) && TravelTextBox.isChecked && !SportsTextBox.isChecked && !PoliticsTextBox.isChecked && !EntrepreneursTextBox.isChecked && !BusinessTextBox.isChecked && !ArtsCheckBox.isChecked
            ) {
                val searchQuery: String = search_query_edittext.text.toString()
                        val query = searchQuery
                        val travelCategory: String = "Travel"

                        val intent = Intent(this@SearchActivity, ResultsActivity::class.java)
                        intent.putExtra("query", query)
                        intent.putExtra("travelCategory", travelCategory)
                        startActivity(intent)
                }
            }

        }

    }

Моя результативная активность:

class ResultsActivity : AppCompatActivity() {

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

        val bundle: Bundle? = intent.extras
        val myQuery = bundle!!.getString("query")
        val myTravelCategory = bundle!!.getString("travelCategory")
        if (bundle.containsKey("query") && bundle.containsKey("travelCategory")) {
            lifecycleScope.launch(IO) {
                val result = ApiClient.getClient.getSearchResultWithCheckbox(query = myQuery!!,
                    category = myTravelCategory!!,
                    api_key = (MYAPIKEY)
                withContext(Main) {
                    SearchResultsRecyclerView.apply {
                        layoutManager = LinearLayoutManager(this@ResultsActivity)
                        adapter = SearchResultsAdapter(result.response.docs)
                    }
                }
            }

        }

    }
}

Как видите, я достаточно закодировал чтобы скрыть ввод пользователя в поисковый запрос, чтобы установить флажок путешествия и нажать клавишу ВВОД, существует еще 145 комбинаций (поисковый запрос + дата начала + флажок политики, поисковый запрос + дата окончания + флажок спорта и т. д. c et c ..) Как я могу добавить все другие комбинации без использования очень длинного блока If / Else?

Что-нибудь в pu sh в правильном направлении было бы h очень признателен, спасибо!

1 Ответ

0 голосов
/ 09 июля 2020

проверьте необходимое условие, а не комбинации, которые его создают. Проверьте, заполнен ли поисковый запрос и установлен ли хотя бы один флажок. Не зная, как работает API, трудно рекомендовать конкретный способ передачи данных, но использование типов, допускающих значение NULL, и / или дополнительных параметров должно работать примерно так:

private fun getCheckedCategories() : List<String> = listOfNotNull(
    "Travel".takeIf { TravelTextBox.isChecked },
    ...
)

private fun atLeastOneCheckBoxChecked() = getCheckedCategories().isNotEmpty()

С помощью этих вспомогательных функций вы можете создайте слушателя, подобного этому:

searchButton.setOnClickListener {
if (search_query_edittext.text.isNotEmpty() && atLeastOneCheckBoxChecked()) {
    val searchQuery: String = search_query_edittext.text.toString()
    val checkedCategories = getCheckedCategories()
    val beginDate : String? = TODO()
    val endDate : String? = TODO()

    val intent = Intent(this@SearchActivity, ResultsActivity::class.java)
    intent.putExtra("query", searchQuery)
    intent.putStringArrayList("checkedCategories", ArrayList(checkedCategories))
    intent.putExtra("beginDate", beginDate)
    intent.putExtra("endDate", endDate)
    startActivity(intent)
}
}

С другой стороны, bundle?.getString("beginDate") вернет null, если он не передан, и любое значение, которое оно имеет, если оно передано. Или получите список переданных флажков с помощью bundle?getStringArrayList("checkedCategories").orEmpty()

...