Как сохранить выделение в диалоговом окне множественного выбора в Android при вращении? - PullRequest
0 голосов
/ 15 июня 2019

У меня есть диалог для выбора более чем одного дня недели следующим образом:

class DialogSettingsEnabledDays : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

        return activity.let {

            val selectedDaysValue = BooleanArray(7) { _ -> false }
            val selectedDaysIndex = ArrayList<Int>()

            val daysToIndexMap = mutableMapOf<String, Int>()
            val indexToDaysMap = mutableMapOf<Int, String>()
            val daysArray = resources.getStringArray(R.array.days_medium)
            for (i in 0..6) {
                daysToIndexMap[daysArray[i]] = i
                indexToDaysMap[i] = daysArray[i]
            }

            val prefs = it!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
            val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
            val selectedDays = selectedDaysString!!.split(", ")

            for (day in selectedDays) {
                selectedDaysValue[daysToIndexMap.getValue(day)] = true
                selectedDaysIndex.add(daysToIndexMap.getValue(day))
            }

            val enabledDaysBuilder = AlertDialog.Builder(it)
            enabledDaysBuilder
                .setTitle(R.string.settings_enabled_days)
                .setMultiChoiceItems(R.array.days_long, selectedDaysValue) { _, which, isChecked ->
                    if (isChecked)
                        selectedDaysIndex.add(which)
                    else if (selectedDaysIndex.contains(which))
                        selectedDaysIndex.remove(Integer.valueOf(which))
                }
                .setPositiveButton(R.string.dialog_ok) { _, _ ->
                    if (selectedDaysIndex.isEmpty()) {
                        Toast.makeText(it, "Select atleast one day !!", Toast.LENGTH_SHORT).show()
                    } else {
                        selectedDaysIndex.sort()
                        val selectedDaysList = mutableListOf<String>()
                        for (i in selectedDaysIndex) {
                            selectedDaysList.add(indexToDaysMap.getValue(i))
                        }
                        val editor = prefs.edit()
                        editor
                            .putString("enabled_days", selectedDaysList.joinToString())
                            .apply()
                        val enabledDays = it.findViewById<LinearLayout>(R.id.settings_enabled_days)
                        enabledDays.findViewById<TextView>(R.id.secondary_text).text = selectedDaysList.joinToString()
                    }
                }
                .setNegativeButton(R.string.dialog_cancel) { _, _ -> /* do nothing */ }

            enabledDaysBuilder.create()
        }
    }
}

И я так называю этот диалог из своей деятельности:

findViewById<LinearLayout>(R.id.settings_enabled_days)
    .setOnClickListener {
        DialogSettingsEnabledDays().show(this.supportFragmentManager, null)
}

Моя проблема в том, что мой выбор дней сбрасывается по умолчанию при ротации. По умолчанию я имею в виду выбор, сохраненный в SharedPreferences, то есть selectedDaysValue в .setMultiChoiceItems. Предположим, это выбранные дни, когда всплывает диалоговое окно:

Mon, Tue, Wed, Thu, Fri

Теперь я изменяю выбор на:

Mon, Tue

Но, когда я поворачиваю телефон, выбор возвращается к значению по умолчанию:

Mon, Tue, Wed, Thu, Fri

Как сохранить выбор при смене ориентации? Потому что в некоторых приложениях, которые я видел, выбор Диалога остается неизменным при вращении.

Ответы [ 2 ]

1 голос
/ 15 июня 2019

Система Android автоматически восстановит ваше состояние фрагмента, в то время как фрагмент, измененный в состоянии, на самом деле не разрушается, а воссоздается только его вид, так что любое значение внутри переменных фрагмента будет сохранено как есть, все, что вам нужно сделать переназначить значение этой переменной на ваш взгляд, вот ссылка https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en

0 голосов
/ 15 июня 2019

Что ж, это окончательное решение, которое я принял, внеся изменения только в код DialogFragment:

Изменение объема сохраняемых данных:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return activity.let {
        val selectedDaysValue = BooleanArray(7) { _ -> false }
        val selectedDaysIndex = ArrayList<Int>()

на:

private var selectedDaysValue = BooleanArray(7) { _ -> false }
private var selectedDaysIndex = ArrayList<Int>()

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return activity.let {

Хранение данных:

override fun onSaveInstanceState(outState: Bundle) {
    outState.putBooleanArray("selected_days_value", this.selectedDaysValue)
    outState.putIntegerArrayList("selected_days_index", this.selectedDaysIndex)
}

И где я читаю данные как:

val prefs = it!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
val selectedDays = selectedDaysString!!.split(", ")

for (day in selectedDays) {
    selectedDaysValue[daysToIndexMap.getValue(day)] = true
    selectedDaysIndex.add(daysToIndexMap.getValue(day))
}

для чтения из сохраненного состояния как:

val prefs = activity!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
if (savedInstanceState == null) {
    val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
    val selectedDays = selectedDaysString!!.split(", ")

    for (day in selectedDays) {
        selectedDaysValue[daysToIndexMap.getValue(day)] = true
        selectedDaysIndex.add(daysToIndexMap.getValue(day))
    }
} else {
    with(savedInstanceState) {
        selectedDaysValue = getBooleanArray("selected_days_value")!!
        selectedDaysIndex = getIntegerArrayList("selected_days_index")!!
    }
}
...