From 4108cf2c7c88c61458671b6805f85eec567727a6 Mon Sep 17 00:00:00 2001 From: Michatec Date: Sat, 28 Mar 2026 21:25:50 +0100 Subject: [PATCH] feat(ui): add TV-specific preference layouts for focus visibility --- .../com/michatec/radio/SettingsFragment.kt | 57 +++++++++++++++++++ .../drawable/selector_preference_focus.xml | 20 +++++++ .../res/layout-television/preference_tv.xml | 14 +++++ 3 files changed, 91 insertions(+) create mode 100644 app/src/main/res/drawable/selector_preference_focus.xml create mode 100644 app/src/main/res/layout-television/preference_tv.xml diff --git a/app/src/main/java/com/michatec/radio/SettingsFragment.kt b/app/src/main/java/com/michatec/radio/SettingsFragment.kt index a16b312..2451588 100644 --- a/app/src/main/java/com/michatec/radio/SettingsFragment.kt +++ b/app/src/main/java/com/michatec/radio/SettingsFragment.kt @@ -46,6 +46,11 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true) (activity as AppCompatActivity).supportActionBar?.title = getString(R.string.fragment_settings_title) requireActivity().window.navigationBarColor = getColor(requireContext(), android.R.attr.colorBackground) + + // Set TV-specific layout for preferences to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + listView.setBackgroundResource(R.drawable.selector_preference_focus) + } } /* Overrides onCreatePreferences from PreferenceFragmentCompat */ @@ -85,6 +90,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList return@setOnPreferenceChangeListener false } } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceThemeSelection.layoutResource = R.layout.preference_tv + } // set up "Update Station Images" preference val preferenceUpdateStationImages = Preference(activity as Context) @@ -101,6 +110,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList ) return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceUpdateStationImages.layoutResource = R.layout.preference_tv + } // set up "Update Stations" preference @@ -118,6 +131,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList ) return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceUpdateCollection.layoutResource = R.layout.preference_tv + } // set up "M3U Export" preference @@ -129,6 +146,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList openSaveM3uDialog() return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceM3uExport.layoutResource = R.layout.preference_tv + } // set up "PLS Export" preference @@ -140,6 +161,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList openSavePlsDialog() return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferencePlsExport.layoutResource = R.layout.preference_tv + } // set up "Backup Stations" preference @@ -151,6 +176,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList openBackupCollectionDialog() return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceBackupCollection.layoutResource = R.layout.preference_tv + } // set up "Restore Stations" preference @@ -162,6 +191,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList openRestoreCollectionDialog() return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceRestoreCollection.layoutResource = R.layout.preference_tv + } // set up "Buffer Size" preference @@ -172,6 +205,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceBufferSize.summaryOn = getString(R.string.pref_buffer_size_summary_enabled) preferenceBufferSize.summaryOff = getString(R.string.pref_buffer_size_summary_disabled) preferenceBufferSize.setDefaultValue(PreferencesHelper.loadLargeBufferSize()) + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceBufferSize.layoutResource = R.layout.preference_tv + } // set up "Edit Stream Address" preference @@ -183,6 +220,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceEnableEditingStreamUri.summaryOff = getString(R.string.pref_edit_station_stream_summary_disabled) preferenceEnableEditingStreamUri.setDefaultValue(PreferencesHelper.loadEditStreamUrisEnabled(context)) preferenceEnableEditingStreamUri.isEnabled = PreferencesHelper.loadEditStreamUrisEnabled(context) + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceEnableEditingStreamUri.layoutResource = R.layout.preference_tv + } // set up "Edit Stations" preference @@ -205,6 +246,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList } return@setOnPreferenceChangeListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceEnableEditingGeneral.layoutResource = R.layout.preference_tv + } // set up "App Version" preference @@ -223,6 +268,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList } return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceAppVersion.layoutResource = R.layout.preference_tv + } // set up "GitHub" preference @@ -239,6 +288,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList startActivity(intent) return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceGitHub.layoutResource = R.layout.preference_tv + } // set up "License" preference val preferenceLicense = Preference(context) @@ -254,6 +307,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList startActivity(intent) return@setOnPreferenceClickListener true } + // Set TV layout for preference to ensure focus is visible + if (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_TYPE_MASK == android.content.res.Configuration.UI_MODE_TYPE_TELEVISION) { + preferenceLicense.layoutResource = R.layout.preference_tv + } // set preference categories diff --git a/app/src/main/res/drawable/selector_preference_focus.xml b/app/src/main/res/drawable/selector_preference_focus.xml new file mode 100644 index 0000000..2b2c10e --- /dev/null +++ b/app/src/main/res/drawable/selector_preference_focus.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-television/preference_tv.xml b/app/src/main/res/layout-television/preference_tv.xml new file mode 100644 index 0000000..ed1cee3 --- /dev/null +++ b/app/src/main/res/layout-television/preference_tv.xml @@ -0,0 +1,14 @@ + + + + + +