如何在 Android 旋转时保留多选对话框中的选择?
How to retain selection in multi choice dialog in Android on rotation?
我有一个对话 select 一周中不止一天如下:
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()
}
}
}
我从 activity:
中以这种方式调用此对话框
findViewById<LinearLayout>(R.id.settings_enabled_days)
.setOnClickListener {
DialogSettingsEnabledDays().show(this.supportFragmentManager, null)
}
我的问题是我的 selection of days 在轮换时重置为默认值。
默认情况下,我指的是存储在 SharedPreferences
中的 selection,即 .setMultiChoiceItems
中的 selectedDaysValue
。
假设,这些是弹出对话框的 selected 天数:
Mon, Tue, Wed, Thu, Fri
现在,我将 selection 更改为:
Mon, Tue
但是,当我旋转 phone 时,selection 设置回默认值:
Mon, Tue, Wed, Thu, Fri
如何在方向改变时保留我的 select离子?
因为在我看到的一些应用程序中,对话框 selection 在旋转时保持不变。
Android 系统会自动恢复你的片段状态,而状态改变的片段实际上并没有被销毁,只是它的视图被重新创建,所以你的片段变量中的任何值都将保持原样,您所要做的就是将该变量值重新分配给您的视图,这里是参考 link https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
好吧,这是我通过仅更改 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")!!
}
}
我有一个对话 select 一周中不止一天如下:
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()
}
}
}
我从 activity:
中以这种方式调用此对话框findViewById<LinearLayout>(R.id.settings_enabled_days)
.setOnClickListener {
DialogSettingsEnabledDays().show(this.supportFragmentManager, null)
}
我的问题是我的 selection of days 在轮换时重置为默认值。
默认情况下,我指的是存储在 SharedPreferences
中的 selection,即 .setMultiChoiceItems
中的 selectedDaysValue
。
假设,这些是弹出对话框的 selected 天数:
Mon, Tue, Wed, Thu, Fri
现在,我将 selection 更改为:
Mon, Tue
但是,当我旋转 phone 时,selection 设置回默认值:
Mon, Tue, Wed, Thu, Fri
如何在方向改变时保留我的 select离子? 因为在我看到的一些应用程序中,对话框 selection 在旋转时保持不变。
Android 系统会自动恢复你的片段状态,而状态改变的片段实际上并没有被销毁,只是它的视图被重新创建,所以你的片段变量中的任何值都将保持原样,您所要做的就是将该变量值重新分配给您的视图,这里是参考 link https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
好吧,这是我通过仅更改 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")!!
}
}