feat(ui): add TV-specific preference layouts for focus visibility

This commit is contained in:
2026-03-28 21:25:50 +01:00
parent f038e01981
commit 4108cf2c7c
3 changed files with 91 additions and 0 deletions

View File

@@ -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

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<shape android:shape="rectangle">
<solid android:color="@color/list_card_stroke_focused" />
<corners android:radius="8dp" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/list_card_stroke_focused" />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@android:color/transparent" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_preference_focus"
android:orientation="vertical"
android:padding="8dp">
<androidx.preference.PreferenceViewHolder
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>