feat(ui): add custom theme color support and share app functionality

Introduce a new custom theme feature that allows users to personalize the application background color using RGB sliders, hex input, or a set of predefined palettes.

Key changes include:
* **Custom Theme Engine**: Added `CustomThemeFragment` and `ThemeHelper` to manage color selection and application. The UI dynamically updates the background color across the `MainActivity` and `PlayerFragment` when preferences change.
* **Android TV Support**: Provided a specialized layout for television devices (`fragment_custom_theme.xml` in `layout-television`) with optimized focus handling for D-pad navigation.
* **Share Feature**: Implemented a "Share App" preference in `SettingsFragment` that triggers a standard Android share intent and displays a thank-you notification upon use.
* **Localization**: Added Ukrainian language support and updated string resources for multiple locales (DE, DA, EL, FR, JA, NL, PL, RU) to include the new theme and share options.
* **Persistence**: Updated `PreferencesHelper` and `Keys` to store theme-related settings, including the enabled state, selected color, and predefined color index.
This commit is contained in:
2026-06-01 19:32:46 +02:00
parent 4429ed4057
commit 181ebd47df
29 changed files with 947 additions and 3 deletions
@@ -0,0 +1,207 @@
package com.michatec.radio
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.toColorInt
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputEditText
import com.michatec.radio.helpers.PreferencesHelper
import com.michatec.radio.helpers.ThemeHelper
class CustomThemeFragment : Fragment() {
private lateinit var colorPreview: View
private lateinit var hexCode: TextInputEditText
private lateinit var seekRed: SeekBar
private lateinit var seekGreen: SeekBar
private lateinit var seekBlue: SeekBar
private lateinit var recyclerView: RecyclerView
private var currentColor: Int = Color.BLACK
private var isUpdatingFromHex = false
private fun applyColor(
color: Int
) {
updateSeekBars(color)
updatePreview(color)
}
private val isAndroidTV: Boolean by lazy {
requireContext().packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_custom_theme, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as? AppCompatActivity)?.supportActionBar?.title = getString(R.string.pref_custom_theme_title)
colorPreview = view.findViewById(R.id.color_preview)
hexCode = view.findViewById(R.id.hex_code)
seekRed = view.findViewById(R.id.seek_red)
seekGreen = view.findViewById(R.id.seek_green)
seekBlue = view.findViewById(R.id.seek_blue)
recyclerView = view.findViewById(R.id.color_recycler_view)
currentColor = PreferencesHelper.loadCustomThemeColor(requireContext())
applyColor(currentColor)
val seekBarListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
val r = seekRed.progress
val g = seekGreen.progress
val b = seekBlue.progress
currentColor = Color.rgb(r, g, b)
updatePreview(currentColor)
PreferencesHelper.saveCustomTheme(currentColor, -1)
(recyclerView.adapter as? ColorAdapter)?.resetSelection()
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
}
seekRed.setOnSeekBarChangeListener(seekBarListener)
seekGreen.setOnSeekBarChangeListener(seekBarListener)
seekBlue.setOnSeekBarChangeListener(seekBarListener)
// Clipboard logic (Non-TV)
if (!isAndroidTV) {
hexCode.setOnClickListener {
copyToClipboard(hexCode.text.toString())
}
hexCode.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (!isUpdatingFromHex) {
try {
val color = s.toString().toColorInt()
currentColor = color
isUpdatingFromHex = true
applyColor(color)
PreferencesHelper.saveCustomTheme(currentColor, -1)
(recyclerView.adapter as? ColorAdapter)?.resetSelection()
isUpdatingFromHex = false
} catch (_: Exception) {}
}
}
override fun afterTextChanged(s: Editable?) {}
})
} else {
hexCode.isFocusable = false
hexCode.isFocusableInTouchMode = false
}
setupRecyclerView()
}
private fun copyToClipboard(text: String) {
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(getString(R.string.hex_code), text)
clipboard.setPrimaryClip(clip)
Toast.makeText(requireContext(), R.string.toastmessage_copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
private fun updateSeekBars(color: Int) {
seekRed.progress = Color.red(color)
seekGreen.progress = Color.green(color)
seekBlue.progress = Color.blue(color)
}
private fun updatePreview(color: Int) {
colorPreview.setBackgroundColor(color)
if (!isUpdatingFromHex) {
isUpdatingFromHex = true
hexCode.setText(String.format("#%08X", 0xFFFFFF and color))
isUpdatingFromHex = false
}
}
private fun setupRecyclerView() {
recyclerView.layoutManager = GridLayoutManager(requireContext(), 5)
val colors = ThemeHelper.getPredefinedColors(requireContext())
val adapter = ColorAdapter(colors) { color, index ->
currentColor = color
applyColor(color)
PreferencesHelper.saveCustomTheme(currentColor, index)
}
recyclerView.adapter = adapter
}
private inner class ColorAdapter(
private val colors: List<Int>,
private val onColorSelected: (Int, Int) -> Unit
) : RecyclerView.Adapter<ColorAdapter.ViewHolder>() {
private var selectedPosition: Int = -1
init {
selectedPosition = PreferencesHelper.loadCustomThemeIndex()
}
fun resetSelection() {
val oldPos = selectedPosition
selectedPosition = -1
if (oldPos != -1) notifyItemChanged(oldPos)
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val circle: View = view.findViewById(R.id.color_circle)
init {
view.isFocusable = true
view.isFocusableInTouchMode = isAndroidTV
view.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION) {
val oldPos = selectedPosition
selectedPosition = pos
if (oldPos != -1) notifyItemChanged(oldPos)
notifyItemChanged(selectedPosition)
onColorSelected(colors[pos], pos)
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.element_color_circle, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val color = colors[position]
val drawable = holder.circle.background as GradientDrawable
drawable.setColor(color)
// Set selection state
holder.itemView.isSelected = (position == selectedPosition)
}
override fun getItemCount() = colors.size
}
}
@@ -92,6 +92,9 @@ object Keys {
const val PREF_PRESET_DRC: String = "PRESET_DRC"
const val PREF_PRESET_STEREO_WIDTH: String = "PRESET_STEREO_WIDTH"
const val PREF_LANGUAGE_SELECTED: String = "PRESET_LANGUAGE_SELECTED"
const val PREF_CUSTOM_THEME_COLOR: String = "CUSTOM_THEME_COLOR"
const val PREF_CUSTOM_THEME_ENABLED: String = "CUSTOM_THEME_ENABLED"
const val PREF_CUSTOM_THEME_INDEX: String = "CUSTOM_THEME_INDEX"
// default const values
const val DEFAULT_SIZE_OF_METADATA_HISTORY: Int = 25
@@ -7,6 +7,7 @@ import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.net.Uri
import android.util.TypedValue
import android.os.Build
import android.os.Bundle
import android.os.Handler
@@ -28,6 +29,7 @@ import com.michatec.radio.helpers.AppThemeHelper
import com.michatec.radio.helpers.FileHelper
import com.michatec.radio.helpers.LanguageHelper
import com.michatec.radio.helpers.PreferencesHelper
import com.michatec.radio.helpers.ThemeHelper
import org.woheller69.freeDroidWarn.FreeDroidWarn
import java.util.Locale
@@ -38,6 +40,7 @@ class MainActivity : AppCompatActivity() {
/* Main class variables */
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var mainRoot: View
// Check if the device running the app is an Android TV instance
private val isAndroidTV: Boolean by lazy {
@@ -94,6 +97,8 @@ class MainActivity : AppCompatActivity() {
// set up views
setContentView(R.layout.activity_main)
mainRoot = findViewById(R.id.main_root)
applyCustomTheme()
// create .nomedia file - if not yet existing
FileHelper.createNomediaFile(getExternalFilesDir(null))
@@ -136,6 +141,33 @@ class MainActivity : AppCompatActivity() {
}
}
private fun applyCustomTheme() {
val enabled = PreferencesHelper.loadCustomThemeEnabled()
if (enabled) {
var color = PreferencesHelper.loadCustomThemeColor(this)
val index = PreferencesHelper.loadCustomThemeIndex()
if (index != -1) {
// Color belongs to a predefined group. Update it based on current mode.
val colors = ThemeHelper.getPredefinedColors(this)
if (index < colors.size) {
val updatedColor = colors[index]
if (updatedColor != color) {
color = updatedColor
// Save the updated color to keep preferences in sync with the current mode
PreferencesHelper.saveCustomThemeColor(color)
}
}
}
mainRoot.setBackgroundColor(color)
} else {
// Reset to default theme background color
val typedValue = TypedValue()
theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true)
mainRoot.setBackgroundColor(typedValue.data)
}
}
/* Overrides onResume from AppCompatActivity */
override fun onResume() {
@@ -176,6 +208,9 @@ class MainActivity : AppCompatActivity() {
Keys.PREF_LANGUAGE_SELECTED -> {
LanguageHelper.setLanguage(this, PreferencesHelper.loadSelectedLanguage())
}
Keys.PREF_CUSTOM_THEME_COLOR, Keys.PREF_CUSTOM_THEME_ENABLED, Keys.PREF_CUSTOM_THEME_INDEX -> {
applyCustomTheme()
}
}
}
/*
@@ -308,6 +308,9 @@ class PlayerFragment : Fragment(),
if (key == Keys.PREF_PLAYER_METADATA_HISTORY) {
requestMetadataUpdate()
}
if (key == Keys.PREF_CUSTOM_THEME_COLOR || key == Keys.PREF_CUSTOM_THEME_ENABLED || key == Keys.PREF_CUSTOM_THEME_INDEX) {
layout.applyCustomTheme(activity as Context)
}
}
@@ -265,6 +265,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
return@setOnPreferenceClickListener true
}
// set up "Visualizer" preference entry
val preferenceVisualizer = Preference(context)
preferenceVisualizer.title = getString(R.string.pref_visualizer_title)
preferenceVisualizer.setIcon(R.drawable.ic_visualizer_24dp)
@@ -349,6 +350,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
return@setOnPreferenceClickListener true
}
// set up "Language Selection" preference
val preferenceLanguageSelection = Preference(context)
preferenceLanguageSelection.title = getString(R.string.pref_language_selection_title)
preferenceLanguageSelection.setIcon(R.drawable.ic_language_24dp)
@@ -361,6 +363,61 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
return@setOnPreferenceClickListener true
}
// set up "Custom Theme" preference
val preferenceCustomTheme = Preference(context)
preferenceCustomTheme.title = getString(R.string.pref_custom_theme_title)
preferenceCustomTheme.setIcon(R.drawable.ic_rbrush_24dp)
preferenceCustomTheme.summary = getString(R.string.pref_custom_theme_summary)
preferenceCustomTheme.isEnabled = PreferencesHelper.loadCustomThemeEnabled()
preferenceCustomTheme.setOnPreferenceClickListener {
findNavController().navigate(R.id.action_settings_to_cstheme)
return@setOnPreferenceClickListener true
}
// set up "Custom Theme Enabled" preference
val preferenceCustomThemeEnabled = MarqueeSwitchPreference(context)
preferenceCustomThemeEnabled.title = getString(R.string.pref_custom_theme_enabled_title)
preferenceCustomThemeEnabled.setIcon(R.drawable.ic_rbrush_24dp)
preferenceCustomThemeEnabled.summaryOn = getString(R.string.pref_custom_theme_enabled_summary)
preferenceCustomThemeEnabled.summaryOff = getString(R.string.pref_custom_theme_disabled_summary)
preferenceCustomThemeEnabled.key = Keys.PREF_CUSTOM_THEME_ENABLED
preferenceCustomThemeEnabled.setDefaultValue(PreferencesHelper.loadCustomThemeEnabled())
preferenceCustomThemeEnabled.setOnPreferenceChangeListener { _, newValue ->
when (newValue) {
true -> {
// enable custom theme
preferenceCustomTheme.isEnabled = true
}
false -> {
// disable custom theme
preferenceCustomTheme.isEnabled = false
}
}
return@setOnPreferenceChangeListener true
}
// set up "Share the App" preference
val preferenceShareApp = Preference(context)
preferenceShareApp.title = getString(R.string.pref_share_app_title)
preferenceShareApp.setIcon(R.drawable.ic_share_24dp)
preferenceShareApp.summary = getString(R.string.pref_share_app_summary)
preferenceShareApp.setOnPreferenceClickListener {
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.app_name))
putExtra(Intent.EXTRA_TEXT, getString(R.string.pref_share_app_share_text))
}
startActivity(shareIntent)
if (!isAndroidTV && isPermissionGranted(activity as Context, android.Manifest.permission.POST_NOTIFICATIONS)) {
NotificationSys.showNotification(
context,
getString(R.string.pref_share_app_thank_title),
getString(R.string.pref_share_app_thank_message)
)
}
return@setOnPreferenceClickListener true
}
// set preference categories
val preferenceCategoryGeneral = PreferenceCategory(activity as Context)
@@ -384,10 +441,13 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
// setup preference screen
screen.addPreference(preferenceAppVersion)
screen.addPreference(preferenceShareApp)
screen.addPreference(preferenceCategoryGeneral)
preferenceCategoryGeneral.addPreference(preferenceThemeSelection)
preferenceCategoryGeneral.addPreference(preferenceLanguageSelection)
preferenceCategoryGeneral.addPreference(preferenceCustomThemeEnabled)
preferenceCategoryGeneral.addPreference(preferenceCustomTheme)
if (!isAndroidTV && isPermissionGranted(activity as Context, android.Manifest.permission.POST_NOTIFICATIONS)) {
preferenceCategoryGeneral.addPreference(preferenceTestNotification)
@@ -39,6 +39,7 @@ class LanguageSelectionDialog(private var languageSelectionDialogListener: Langu
Language("de", R.string.pref_language_de),
Language("fr", R.string.pref_language_fr),
Language("ru", R.string.pref_language_ru),
Language("uk", R.string.pref_language_uk),
Language("ja", R.string.pref_language_ja),
Language("nl", R.string.pref_language_nl),
Language("pl", R.string.pref_language_pl),
@@ -4,12 +4,14 @@ import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.util.Log
import android.util.TypedValue
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.google.gson.Gson
import com.michatec.radio.Keys
import com.michatec.radio.ui.PlayerState
import java.util.*
import java.util.Calendar
import java.util.Date
/*
@@ -362,4 +364,33 @@ object PreferencesHelper {
}
}
/* Loads custom theme color */
fun loadCustomThemeColor(context: Context): Int {
val typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true)
return sharedPreferences.getInt(Keys.PREF_CUSTOM_THEME_COLOR, typedValue.data)
}
/* Saves custom theme color */
fun saveCustomThemeColor(color: Int) {
sharedPreferences.edit { putInt(Keys.PREF_CUSTOM_THEME_COLOR, color) }
}
/* Loads custom theme index (predefined color index) */
fun loadCustomThemeIndex(): Int {
return sharedPreferences.getInt(Keys.PREF_CUSTOM_THEME_INDEX, -1)
}
/* Saves custom theme color and index together */
fun saveCustomTheme(color: Int, index: Int) {
sharedPreferences.edit {
putInt(Keys.PREF_CUSTOM_THEME_COLOR, color)
putInt(Keys.PREF_CUSTOM_THEME_INDEX, index)
}
}
/* Loads whether custom theme is enabled */
fun loadCustomThemeEnabled(): Boolean {
return sharedPreferences.getBoolean(Keys.PREF_CUSTOM_THEME_ENABLED, false)
}
}
@@ -0,0 +1,40 @@
package com.michatec.radio.helpers
import android.content.Context
import android.content.res.Configuration
import androidx.core.graphics.toColorInt
object ThemeHelper {
fun getPredefinedColors(context: Context): List<Int> {
val isDarkMode = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
return if (isDarkMode) {
// Darker colors for dark mode background
listOf(
"#FF1D3E66".toColorInt(), // Default Dark
"#FF3E1D1D".toColorInt(), // Red Dark
"#FF1D3E3E".toColorInt(), // Teal Dark
"#FF3E1D2E".toColorInt(), // Pink Dark
"#FF001A33".toColorInt(), // Dark Blue Dark
"#FF1D3E1D".toColorInt(), // Green Dark
"#FF3E2E1D".toColorInt(), // Orange Dark
"#FF2E1D1D".toColorInt(), // Brown Dark
"#FF1D242E".toColorInt(), // Blue Grey Dark
"#FF000000".toColorInt() // Black
)
} else {
// Lighter colors for light mode background
listOf(
"#FFDAE2FF".toColorInt(), // Light Default
"#FFFF897D".toColorInt(), // Light Red
"#FF4DB6AC".toColorInt(), // Light Teal
"#FFF48FB1".toColorInt(), // Light Pink
"#FF90CAF9".toColorInt(), // Light Blue
"#FFA5D6A7".toColorInt(), // Light Green
"#FFFFAB91".toColorInt(), // Light Orange
"#FFBCAAA4".toColorInt(), // Light Brown
"#FFB0BEC5".toColorInt(), // Light Blue Grey
"#FFFFFFFF".toColorInt() // White
)
}
}
}
@@ -6,7 +6,6 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.AnimatedVectorDrawable
import java.util.Locale
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
@@ -31,7 +30,9 @@ import com.michatec.radio.core.Station
import com.michatec.radio.helpers.DateTimeHelper
import com.michatec.radio.helpers.ImageHelper
import com.michatec.radio.helpers.PreferencesHelper
import com.michatec.radio.helpers.ThemeHelper
import com.michatec.radio.helpers.UiHelper
import java.util.Locale
/*
@@ -122,6 +123,9 @@ data class LayoutHolder(var rootView: View) {
CastButtonFactory.setUpMediaRouteButton(rootView.context, it)
}
// Apply custom theme color
applyCustomTheme(rootView.context)
// set layout for player
setupBottomSheet()
}
@@ -182,6 +186,9 @@ data class LayoutHolder(var rootView: View) {
// update bitrate
sheetBitrateView?.text = bitrateText
// update custom theme
applyCustomTheme(context)
// update click listeners
sheetStreamingLinkHeadline?.setOnClickListener {
copyToClipboard(
@@ -309,6 +316,28 @@ data class LayoutHolder(var rootView: View) {
isBuffering = buffering
}
/* Applies custom theme color to the UI */
fun applyCustomTheme(context: Context) {
val enabled = PreferencesHelper.loadCustomThemeEnabled()
if (enabled) {
var customColor = PreferencesHelper.loadCustomThemeColor(context)
val index = PreferencesHelper.loadCustomThemeIndex()
if (index != -1) {
val colors = ThemeHelper.getPredefinedColors(context)
if (index < colors.size) {
customColor = colors[index]
}
}
rootView.setBackgroundColor(customColor)
recyclerView.setBackgroundColor(customColor)
} else {
rootView.setBackgroundResource(android.R.color.transparent)
recyclerView.setBackgroundResource(android.R.color.transparent)
}
}
/* Toggles visibility of the download progress indicator */
fun toggleDownloadProgressIndicator() {
when (PreferencesHelper.loadActiveDownloads()) {
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="@color/icon_default"
android:pathData="M7,14c-1.66,0 -3,1.34 -3,3 0,1.31 -1.16,2 -2,2 0.92,1.22 2.49,2 4,2 2.21,0 4,-1.79 4,-4 0,-1.66 -1.34,-3 -3,-3zM20.71,4.63l-1.34,-1.34c-0.39,-0.39 -1.02,-0.39 -1.41,0L9,12.25 11.75,15l8.96,-8.96c0.39,-0.39 0.39,-1.02 0,-1.41z"/>
</vector>
+1 -1
View File
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/player_sheet_icon"
android:fillColor="@color/icon_default"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92s2.92,-1.31 2.92,-2.92 -1.31,-2.92 -2.92,-2.92z" />
</vector>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Highlight when focused (TV navigation) -->
<item android:state_focused="true">
<shape android:shape="rectangle">
<solid android:color="#44888888" />
<stroke android:width="3dp" android:color="?attr/colorPrimary" />
<corners android:radius="12dp" />
</shape>
</item>
<!-- Highlight when selected (Active color) -->
<item android:state_selected="true">
<shape android:shape="rectangle">
<stroke android:width="3dp" android:color="?attr/colorSecondary" />
<corners android:radius="12dp" />
</shape>
</item>
<item android:drawable="@android:color/transparent" />
</selector>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/white" />
<stroke android:width="2dp" android:color="#CCCCCC" />
</shape>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="3dp" android:color="#000000" />
<padding android:bottom="8dp" android:left="8dp" android:right="8dp" android:top="8dp" />
<corners android:radius="8dp" />
</shape>
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="horizontal"
android:padding="24dp">
<!-- LEFT SIDE: CONTROLS -->
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.5">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/predefined_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/theme_predefined_colors"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/color_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="5"
tools:listitem="@layout/element_color_circle" />
<TextView
android:id="@+id/custom_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/theme_custom_rgb"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" />
<LinearLayout
android:id="@+id/rgb_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/shape_rgb_controls_border"
android:orientation="vertical">
<TextView
android:id="@+id/red_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/theme_red"
android:textSize="18sp" />
<SeekBar
android:id="@+id/seek_red"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:max="255"
android:focusable="true" />
<TextView
android:id="@+id/green_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/theme_green"
android:textSize="18sp" />
<SeekBar
android:id="@+id/seek_green"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:max="255"
android:focusable="true" />
<TextView
android:id="@+id/blue_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/theme_blue"
android:textSize="18sp" />
<SeekBar
android:id="@+id/seek_blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:max="255"
android:focusable="true" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<!-- RIGHT SIDE: PREVIEW & APPLY -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_rgb_controls_border">
<View
android:id="@+id/color_preview"
android:layout_width="180dp"
android:layout_height="180dp"
android:background="@android:color/black" />
</FrameLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/hex_input_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/hex_code"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="9"
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
tools:text="#FF000000" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</LinearLayout>
@@ -2,6 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground"
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="4dp"
android:focusable="true"
android:clickable="true"
android:background="@drawable/selector_color_circle">
<View
android:id="@+id/color_circle"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/shape_color_circle" />
</FrameLayout>
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:padding="16dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/predefined_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/theme_predefined_colors"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/color_recycler_view"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/color_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/predefined_label"
tools:listitem="@layout/element_color_circle" />
<TextView
android:id="@+id/custom_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/theme_custom_rgb"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/color_recycler_view" />
<LinearLayout
android:id="@+id/rgb_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/shape_rgb_controls_border"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@id/custom_label">
<TextView
android:id="@+id/red_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/theme_red" />
<SeekBar
android:id="@+id/seek_red"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:focusable="true" />
<TextView
android:id="@+id/green_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/theme_green" />
<SeekBar
android:id="@+id/seek_green"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:focusable="true" />
<TextView
android:id="@+id/blue_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/theme_blue" />
<SeekBar
android:id="@+id/seek_blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:focusable="true" />
</LinearLayout>
<FrameLayout
android:id="@+id/color_preview_border"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/shape_rgb_controls_border"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rgb_controls">
<View
android:id="@+id/color_preview"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@android:color/black" />
</FrameLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/hex_input_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/color_preview_border">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/hex_code"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="9"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
tools:text="#FF000000" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
@@ -32,6 +32,9 @@
<action
android:id="@+id/action_settings_to_visualizer"
app:destination="@id/visualizer_destination" />
<action
android:id="@+id/action_settings_to_cstheme"
app:destination="@id/custom_theme_destination" />
</fragment>
<!-- EQUALIZER -->
@@ -52,4 +55,11 @@
android:name="com.michatec.radio.AddStationFragment"
android:label="Add Station"
tools:layout="@layout/dialog_find_station" />
<!-- CUSTOM THEME -->
<fragment
android:id="@+id/custom_theme_destination"
android:name="com.michatec.radio.CustomThemeFragment"
android:label="Custom Theme"
tools:layout="@layout/fragment_custom_theme" />
</navigation>
+19
View File
@@ -159,4 +159,23 @@
<string name="media_route_menu_title">Cast</string>
<string name="pref_visualizer_title">Spektrumanalysator</string>
<string name="pref_visualizer_summary">Vis spektrumanalysatoren.</string>
<string name="pref_share_app_title">Del app</string>
<string name="pref_share_app_summary">Anbefal denne app til en ven.</string>
<string name="pref_share_app_share_text">Tjek denne fantastiske radio-app ud: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Tak skal du have!</string>
<string name="pref_share_app_thank_message">En stor tak til dig fra udviklerne.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Aktiverer fanen for brugerdefineret tema.</string>
<string name="pref_custom_theme_disabled_summary">Deaktiverer fanen for brugerdefineret tema.</string>
<string name="pref_custom_theme_summary">Tilpas applikationens baggrundsfarve.</string>
<string name="pref_custom_theme_title">Brugerdefineret tema</string>
<string name="pref_custom_theme_enabled_title">Aktiver brugerdefineret tema</string>
<string name="theme_predefined_colors">Foruddefinerede farver (Lys/Mørk):</string>
<string name="theme_custom_rgb">Brugerdefineret RGB (tilpas venligst til appen):</string>
<string name="theme_red">Rød</string>
<string name="theme_green">Grøn</string>
<string name="theme_blue">Blå</string>
<string name="hex_code">Hex-kode</string>
</resources>
+19
View File
@@ -160,5 +160,24 @@
<string name="media_route_menu_title">Streamen</string>
<string name="pref_visualizer_title">Spektrumanzeige</string>
<string name="pref_visualizer_summary">Sehe die Spektrumanzeige.</string>
<string name="pref_share_app_title">App teilen</string>
<string name="pref_share_app_summary">Empfehle diese App einem Freund.</string>
<string name="pref_share_app_share_text">Schau dir diese tolle Radio-App an: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Vielen Dank!</string>
<string name="pref_share_app_thank_message">Ein großes Dankeschön von den Entwicklern.</string>
<string name="loading">Lade…</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Aktiviert den Tab für das benutzerdefinierte Design.</string>
<string name="pref_custom_theme_disabled_summary">Deaktiviert den Tab für das benutzerdefinierte Design.</string>
<string name="pref_custom_theme_summary">Passen Sie die Hintergrundfarbe der Anwendung an.</string>
<string name="pref_custom_theme_title">Benutzerdefiniertes Design</string>
<string name="pref_custom_theme_enabled_title">Benutzerdefiniertes Design aktivieren</string>
<string name="theme_predefined_colors">Vordefinierte Farben (Hell/Dunkel):</string>
<string name="theme_custom_rgb">Benutzerdefiniertes RGB (bitte an die App anpassen):</string>
<string name="theme_red">Rot</string>
<string name="theme_green">Grün</string>
<string name="theme_blue">Blau</string>
<string name="hex_code">Hex-Code</string>
</resources>
+19
View File
@@ -161,4 +161,23 @@
<string name="media_route_menu_title">Μετάδοση</string>
<string name="pref_visualizer_title">Αναλυτής Φάσματος</string>
<string name="pref_visualizer_summary">Εμφάνιση του Αναλυτή Φάσματος.</string>
<string name="pref_share_app_title">Κοινοποίηση Εφαρμογής</string>
<string name="pref_share_app_summary">Προτείνετε αυτήν την εφαρμογή σε έναν φίλο.</string>
<string name="pref_share_app_share_text">Δείτε αυτήν την καταπληκτική εφαρμογή ραδιοφώνου: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Σας ευχαριστούμε!</string>
<string name="pref_share_app_thank_message">Ένα μεγάλο ευχαριστώ από τους προγραμματιστές.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Ενεργοποιεί την καρτέλα προσαρμοσμένου θέματος.</string>
<string name="pref_custom_theme_disabled_summary">Απενεργοποιεί την καρτέλα προσαρμοσμένου θέματος.</string>
<string name="pref_custom_theme_summary">Προσαρμόστε το χρώμα φόντου της εφαρμογής.</string>
<string name="pref_custom_theme_title">Προσαρμοσμένο Θέμα</string>
<string name="pref_custom_theme_enabled_title">Ενεργοποίηση Προσαρμοσμένου Θέματος</string>
<string name="theme_predefined_colors">Προκαθορισμένα Χρώματα (Φωτεινό/Σκοτεινό):</string>
<string name="theme_custom_rgb">Προσαρμοσμένο RGB (παρακαλώ προσαρμόστε στην εφαρμογή):</string>
<string name="theme_red">Κόκκινο</string>
<string name="theme_green">Πράσινο</string>
<string name="theme_blue">Μπλε</string>
<string name="hex_code">Κωδικός Hex</string>
</resources>
+19
View File
@@ -159,4 +159,23 @@
<string name="media_route_menu_title">Diffuser</string>
<string name="pref_visualizer_title">Analyseur de spectre</string>
<string name="pref_visualizer_summary">Afficher l analyseur de spectre.</string>
<string name="pref_share_app_title">Partager l\'application</string>
<string name="pref_share_app_summary">Recommandez cette application à un ami.</string>
<string name="pref_share_app_share_text">Découvrez cette super application radio : https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Merci beaucoup !</string>
<string name="pref_share_app_thank_message">Un grand merci de la part des développeurs.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Active l\'onglet du thème personnalisé.</string>
<string name="pref_custom_theme_disabled_summary">Désactive l\'onglet du thème personnalisé.</string>
<string name="pref_custom_theme_summary">Personnalisez la couleur d\'arrière-plan de l\'application.</string>
<string name="pref_custom_theme_title">Thème personnalisé</string>
<string name="pref_custom_theme_enabled_title">Activer le thème personnalisé</string>
<string name="theme_predefined_colors">Couleurs prédéfinies (Clair/Sombre) :</string>
<string name="theme_custom_rgb">RGB personnalisé (veuillez l\'adapter à l\'application) :</string>
<string name="theme_red">Rouge</string>
<string name="theme_green">Vert</string>
<string name="theme_blue">Bleu</string>
<string name="hex_code">Code Hex</string>
</resources>
+19
View File
@@ -160,4 +160,23 @@
<string name="media_route_menu_title">キャスト</string>
<string name="pref_visualizer_title">スペクトラムアナライザー</string>
<string name="pref_visualizer_summary">スペクトラムアナライザーを表示します。</string>
<string name="pref_share_app_title">アプリを共有</string>
<string name="pref_share_app_summary">このアプリを友達に勧める。</string>
<string name="pref_share_app_share_text">この素晴らしいラジオアプリをチェックしてみてください: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">ありがとうございます!</string>
<string name="pref_share_app_thank_message">開発者一同より、心から感謝申し上げます。</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">カスタムテーマタブを有効にします。</string>
<string name="pref_custom_theme_disabled_summary">カスタムテーマタブを無効にします。</string>
<string name="pref_custom_theme_summary">アプリケーションの背景色をカスタマイズします。</string>
<string name="pref_custom_theme_title">カスタムテーマ</string>
<string name="pref_custom_theme_enabled_title">カスタムテーマを有効にする</string>
<string name="theme_predefined_colors">事前定義された色(ライト/ダーク):</string>
<string name="theme_custom_rgb">カスタムRGB(アプリに合わせて調整してください):</string>
<string name="theme_red"></string>
<string name="theme_green"></string>
<string name="theme_blue"></string>
<string name="hex_code">Hexコード</string>
</resources>
+19
View File
@@ -161,4 +161,23 @@
<string name="media_route_menu_title">Cast</string>
<string name="pref_visualizer_title">Spectrum Analyser</string>
<string name="pref_visualizer_summary">Toon de Spectrum Analyser.</string>
<string name="pref_share_app_title">App delen</string>
<string name="pref_share_app_summary">Beveel deze app aan bij een vriend.</string>
<string name="pref_share_app_share_text">Bekijk deze geweldige radio-app: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Bedankt!</string>
<string name="pref_share_app_thank_message">Een groot dankjewel van de ontwikkelaars.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Schakelt het tabblad voor het aangepaste thema in.</string>
<string name="pref_custom_theme_disabled_summary">Schakelt het tabblad voor het aangepaste thema uit.</string>
<string name="pref_custom_theme_summary">Pas de achtergrondkleur van de applicatie aan.</string>
<string name="pref_custom_theme_title">Aangepast Thema</string>
<string name="pref_custom_theme_enabled_title">Aangepast Thema Inschakelen</string>
<string name="theme_predefined_colors">Vooraf gedefinieerde kleuren (Licht/Donker):</string>
<string name="theme_custom_rgb">Aangepaste RGB (pas deze aan de app aan):</string>
<string name="theme_red">Rood</string>
<string name="theme_green">Groen</string>
<string name="theme_blue">Blauw</string>
<string name="hex_code">Hex-code</string>
</resources>
+19
View File
@@ -161,4 +161,23 @@
<string name="media_route_menu_title">Przesyłanie</string>
<string name="pref_visualizer_title">Analizator Widma</string>
<string name="pref_visualizer_summary">Pokaż Analizator Widma.</string>
<string name="pref_share_app_title">Udostępnij aplikację</string>
<string name="pref_share_app_summary">Poleć tę aplikację znajomemu.</string>
<string name="pref_share_app_share_text">Sprawdź tę świetną aplikację radiową: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Dziękujemy!</string>
<string name="pref_share_app_thank_message">Wielkie podziękowania od deweloperów.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Włącza kartę motywu niestandardowego.</string>
<string name="pref_custom_theme_disabled_summary">Wyłącza kartę motywu niestandardowego.</string>
<string name="pref_custom_theme_summary">Dostosuj kolor tła aplikacji.</string>
<string name="pref_custom_theme_title">Motyw niestandardowy</string>
<string name="pref_custom_theme_enabled_title">Włącz motyw niestandardowy</string>
<string name="theme_predefined_colors">Predefiniowane kolory (Jasny/Ciemny):</string>
<string name="theme_custom_rgb">Niestandardowy RGB (proszę dostosować do aplikacji):</string>
<string name="theme_red">Czerwony</string>
<string name="theme_green">Zielony</string>
<string name="theme_blue">Niebieski</string>
<string name="hex_code">Kod Hex</string>
</resources>
+19
View File
@@ -161,4 +161,23 @@
<string name="media_route_menu_title">Трансляция</string>
<string name="pref_visualizer_title">Анализатор спектра</string>
<string name="pref_visualizer_summary">Показать анализатор спектра.</string>
<string name="pref_share_app_title">Поделиться приложением</string>
<string name="pref_share_app_summary">Рекомендовать это приложение другу.</string>
<string name="pref_share_app_share_text">Посмотрите это классное радио-приложение: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Спасибо!</string>
<string name="pref_share_app_thank_message">Большое спасибо от разработчиков.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Включает вкладку пользовательской темы.</string>
<string name="pref_custom_theme_disabled_summary">Отключает вкладку пользовательской темы.</string>
<string name="pref_custom_theme_summary">Настройка цвета фона приложения.</string>
<string name="pref_custom_theme_title">Пользовательская тема</string>
<string name="pref_custom_theme_enabled_title">Включить пользовательскую тему</string>
<string name="theme_predefined_colors">Предустановленные цвета (Светлые/Темные):</string>
<string name="theme_custom_rgb">Пользовательский RGB (пожалуйста, адаптируйте к приложению):</string>
<string name="theme_red">Красный</string>
<string name="theme_green">Зеленый</string>
<string name="theme_blue">Синий</string>
<string name="hex_code">Hex-код</string>
</resources>
+19
View File
@@ -161,4 +161,23 @@
<string name="media_route_menu_title">Трансляція</string>
<string name="pref_visualizer_title">Аналізатор спектру</string>
<string name="pref_visualizer_summary">Показати аналізатор спектру.</string>
<string name="pref_share_app_title">Поділитися застосунком</string>
<string name="pref_share_app_summary">Рекомендувати цей застосунок другу.</string>
<string name="pref_share_app_share_text">Подивіться на цей чудовий радіозастосунок: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Дякуємо!</string>
<string name="pref_share_app_thank_message">Велике спасибі вам від розробників.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Вмикає вкладку користувацької теми.</string>
<string name="pref_custom_theme_disabled_summary">Вимикає вкладку користувацької теми.</string>
<string name="pref_custom_theme_summary">Налаштуйте колір фону застосунку.</string>
<string name="pref_custom_theme_title">Користувацька тема</string>
<string name="pref_custom_theme_enabled_title">Увімкнути користувацьку тему</string>
<string name="theme_predefined_colors">Попередньо визначені кольори (Світлі/Темні):</string>
<string name="theme_custom_rgb">Власний RGB (будь ласка, адаптуйте до застосунку):</string>
<string name="theme_red">Червоний</string>
<string name="theme_green">Зелений</string>
<string name="theme_blue">Синій</string>
<string name="hex_code">Hex-код</string>
</resources>
+19
View File
@@ -74,6 +74,7 @@
<string name="pref_language_pl" translatable="false">🇵🇱 Polski</string>
<string name="pref_language_el" translatable="false">🇬🇷 Ελληνικά</string>
<string name="pref_language_da" translatable="false">🇩🇰 Dansk</string>
<string name="pref_language_uk" translatable="false">🇺🇦 Українська</string>
<!-- Settings -->
@@ -148,6 +149,11 @@
<string name="pref_update_station_images_title">Update Station Images</string>
<string name="pref_test_notification_title">Test Notification</string>
<string name="pref_test_notification_summary">Test whether the notification system works.</string>
<string name="pref_share_app_title">Share App</string>
<string name="pref_share_app_summary">Recommend this app to a friend.</string>
<string name="pref_share_app_share_text">Check out this awesome radio app: https://github.com/michatec/Radio</string>
<string name="pref_share_app_thank_title">Thank You!</string>
<string name="pref_share_app_thank_message">A big thank you to you from the developers.</string>
<!-- Sample Text -->
<string name="sample_text_sleep_timer_remaining_time" translatable="false">00:00</string>
@@ -197,4 +203,17 @@
<string name="media_route_menu_title">Cast</string>
<string name="pref_visualizer_title">Spectrum Analyzer</string>
<string name="pref_visualizer_summary">Show the Spectrum Analyzer.</string>
<!-- Custom Theme -->
<string name="pref_custom_theme_enabled_summary">Enables the custom theme tab.</string>
<string name="pref_custom_theme_disabled_summary">Disables the custom theme tab.</string>
<string name="pref_custom_theme_summary">Customize the application background color.</string>
<string name="pref_custom_theme_title">Custom Theme</string>
<string name="pref_custom_theme_enabled_title">Enable Custom Theme</string>
<string name="theme_predefined_colors">Predefined Colors (Light/Dark):</string>
<string name="theme_custom_rgb">Custom RGB (please adapt to the app):</string>
<string name="theme_red">Red</string>
<string name="theme_green">Green</string>
<string name="theme_blue">Blue</string>
<string name="hex_code">Hex Code</string>
</resources>