style: add basic black theme
Finally add black theme support to Auxio. This is abit of a janky implementation since I had to add an extra set of accents, but it shouldn't be as big of a problem after the styles refactoring. Support for black android components is not implemented yet, but will be eventually.
This commit is contained in:
parent
dc2157904a
commit
68bdd0d929
12 changed files with 232 additions and 25 deletions
|
@ -15,6 +15,7 @@ import org.oxycblt.auxio.playback.system.PlaybackService
|
|||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.isEdgeOn
|
||||
import org.oxycblt.auxio.ui.isNight
|
||||
|
||||
/**
|
||||
* The single [AppCompatActivity] for Auxio.
|
||||
|
@ -25,11 +26,7 @@ class MainActivity : AppCompatActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val settingsManager = SettingsManager.getInstance()
|
||||
val newAccent = Accent.set(settingsManager.accent)
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
|
||||
setTheme(newAccent.theme)
|
||||
setupTheme()
|
||||
|
||||
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
|
||||
this, R.layout.activity_main
|
||||
|
@ -52,6 +49,22 @@ class MainActivity : AppCompatActivity() {
|
|||
onNewIntent(intent)
|
||||
}
|
||||
|
||||
private fun setupTheme() {
|
||||
// Update the current accent and theme
|
||||
val settingsManager = SettingsManager.getInstance()
|
||||
AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
|
||||
|
||||
val newAccent = Accent.set(settingsManager.accent)
|
||||
|
||||
// The black theme has a completely separate set of styles since style attributes cannot
|
||||
// be modified at runtime.
|
||||
if (isNight() && settingsManager.useBlackTheme) {
|
||||
setTheme(newAccent.blackTheme)
|
||||
} else {
|
||||
setTheme(newAccent.theme)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.oxycblt.auxio.settings.blacklist.BlacklistDialog
|
|||
import org.oxycblt.auxio.settings.ui.IntListPrefDialog
|
||||
import org.oxycblt.auxio.settings.ui.IntListPreference
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.isNight
|
||||
import org.oxycblt.auxio.ui.showToast
|
||||
|
||||
/**
|
||||
|
@ -82,6 +83,16 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
}
|
||||
|
||||
SettingsManager.KEY_BLACK_THEME -> {
|
||||
onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
if (requireContext().isNight()) {
|
||||
requireActivity().recreate()
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
SettingsManager.KEY_ACCENT -> {
|
||||
onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
AccentDialog().show(childFragmentManager, AccentDialog.TAG)
|
||||
|
|
|
@ -32,6 +32,10 @@ class SettingsManager private constructor(context: Context) :
|
|||
val theme: Int
|
||||
get() = handleThemeCompat(sharedPrefs)
|
||||
|
||||
/** Whether the dark theme should be black or not */
|
||||
val useBlackTheme: Boolean
|
||||
get() = sharedPrefs.getBoolean(KEY_BLACK_THEME, false)
|
||||
|
||||
/** The current accent. */
|
||||
var accent: Accent
|
||||
get() = handleAccentCompat(sharedPrefs)
|
||||
|
@ -195,6 +199,7 @@ class SettingsManager private constructor(context: Context) :
|
|||
|
||||
companion object {
|
||||
const val KEY_THEME = "KEY_THEME2"
|
||||
const val KEY_BLACK_THEME = "KEY_BLACK_THEME"
|
||||
const val KEY_ACCENT = "KEY_ACCENT2"
|
||||
|
||||
const val KEY_LIB_DISPLAY_MODE = "KEY_LIB_MODE"
|
||||
|
|
|
@ -15,34 +15,85 @@ import org.oxycblt.auxio.R
|
|||
* TODO: Add custom accents
|
||||
*/
|
||||
val ACCENTS = arrayOf(
|
||||
Accent(R.color.red, R.style.Theme_Red, R.string.color_label_red),
|
||||
Accent(R.color.pink, R.style.Theme_Pink, R.string.color_label_pink),
|
||||
Accent(R.color.purple, R.style.Theme_Purple, R.string.color_label_purple),
|
||||
Accent(R.color.deep_purple, R.style.Theme_DeepPurple, R.string.color_label_deep_purple),
|
||||
Accent(R.color.indigo, R.style.Theme_Indigo, R.string.color_label_indigo),
|
||||
Accent(R.color.blue, R.style.Theme_Blue, R.string.color_label_blue),
|
||||
Accent(R.color.light_blue, R.style.Theme_LightBlue, R.string.color_label_light_blue),
|
||||
Accent(R.color.cyan, R.style.Theme_Cyan, R.string.color_label_cyan),
|
||||
Accent(R.color.teal, R.style.Theme_Teal, R.string.color_label_teal),
|
||||
Accent(R.color.green, R.style.Theme_Green, R.string.color_label_green),
|
||||
Accent(R.color.light_green, R.style.Theme_LightGreen, R.string.color_label_light_green),
|
||||
Accent(R.color.lime, R.style.Theme_Lime, R.string.color_label_lime),
|
||||
Accent(R.color.yellow, R.style.Theme_Yellow, R.string.color_label_yellow),
|
||||
Accent(R.color.orange, R.style.Theme_Orange, R.string.color_label_orange),
|
||||
Accent(R.color.deep_orange, R.style.Theme_DeepOrange, R.string.color_label_deep_orange),
|
||||
Accent(R.color.brown, R.style.Theme_Brown, R.string.color_label_brown),
|
||||
Accent(R.color.grey, R.style.Theme_Gray, R.string.color_label_grey),
|
||||
Accent(R.color.blue_grey, R.style.Theme_BlueGrey, R.string.color_label_blue_grey),
|
||||
Accent(R.color.red, R.style.Theme_Red, R.style.Theme_Red_Black, R.string.color_label_red),
|
||||
Accent(R.color.pink, R.style.Theme_Pink, R.style.Theme_Pink_Black, R.string.color_label_pink),
|
||||
Accent(
|
||||
R.color.purple,
|
||||
R.style.Theme_Purple,
|
||||
R.style.Theme_Purple_Black,
|
||||
R.string.color_label_purple
|
||||
),
|
||||
Accent(
|
||||
R.color.deep_purple,
|
||||
R.style.Theme_DeepPurple,
|
||||
R.style.Theme_DeepPurple_Black,
|
||||
R.string.color_label_deep_purple
|
||||
),
|
||||
Accent(
|
||||
R.color.indigo,
|
||||
R.style.Theme_Indigo,
|
||||
R.style.Theme_Indigo_Black,
|
||||
R.string.color_label_indigo
|
||||
),
|
||||
Accent(R.color.blue, R.style.Theme_Blue, R.style.Theme_Blue_Black, R.string.color_label_blue),
|
||||
Accent(
|
||||
R.color.light_blue,
|
||||
R.style.Theme_LightBlue,
|
||||
R.style.Theme_LightBlue_Black,
|
||||
R.string.color_label_light_blue
|
||||
),
|
||||
Accent(R.color.cyan, R.style.Theme_Cyan, R.style.Theme_Cyan_Black, R.string.color_label_cyan),
|
||||
Accent(R.color.teal, R.style.Theme_Teal, R.style.Theme_Teal_Black, R.string.color_label_teal),
|
||||
Accent(R.color.green, R.style.Theme_Green, R.style.Theme_Green_Black, R.string.color_label_green),
|
||||
Accent(
|
||||
R.color.light_green,
|
||||
R.style.Theme_LightGreen,
|
||||
R.style.Theme_LightGreen_Black,
|
||||
R.string.color_label_light_green
|
||||
),
|
||||
Accent(R.color.lime, R.style.Theme_Lime, R.style.Theme_Lime_Black, R.string.color_label_lime),
|
||||
Accent(
|
||||
R.color.yellow,
|
||||
R.style.Theme_Yellow,
|
||||
R.style.Theme_Yellow_Black,
|
||||
R.string.color_label_yellow
|
||||
),
|
||||
Accent(
|
||||
R.color.orange,
|
||||
R.style.Theme_Orange,
|
||||
R.style.Theme_Orange_Black,
|
||||
R.string.color_label_orange
|
||||
),
|
||||
Accent(
|
||||
R.color.deep_orange,
|
||||
R.style.Theme_DeepOrange,
|
||||
R.style.Theme_DeepOrange_Black,
|
||||
R.string.color_label_deep_orange
|
||||
),
|
||||
Accent(R.color.brown, R.style.Theme_Brown, R.style.Theme_Brown_Black, R.string.color_label_brown),
|
||||
Accent(R.color.grey, R.style.Theme_Grey, R.style.Theme_Grey_Black, R.string.color_label_grey),
|
||||
Accent(
|
||||
R.color.blue_grey,
|
||||
R.style.Theme_BlueGrey,
|
||||
R.style.Theme_BlueGrey_Black,
|
||||
R.string.color_label_blue_grey
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* The data object for an accent.
|
||||
* @property color The color resource for this accent
|
||||
* @property theme The theme resource for this accent
|
||||
* @property blackTheme The black theme resource for this accent
|
||||
* @property name The name of this accent
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
data class Accent(@ColorRes val color: Int, @StyleRes val theme: Int, @StringRes val name: Int) {
|
||||
data class Accent(
|
||||
@ColorRes val color: Int,
|
||||
@StyleRes val theme: Int,
|
||||
@StyleRes val blackTheme: Int,
|
||||
@StringRes val name: Int
|
||||
) {
|
||||
/**
|
||||
* Get a [ColorStateList] of the accent
|
||||
*/
|
||||
|
|
|
@ -78,6 +78,15 @@ fun <T : Any> Context.getSystemServiceSafe(serviceClass: KClass<T>): T {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current UI is in night mode or not. This will work if the theme is
|
||||
* automatic as well.
|
||||
*/
|
||||
fun Context.isNight(): Boolean {
|
||||
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
|
||||
Configuration.UI_MODE_NIGHT_YES
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a color.
|
||||
* @param context [Context] required
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
android:layout_marginStart="@dimen/spacing_mid_large"
|
||||
android:layout_marginEnd="@dimen/spacing_mid_large"
|
||||
android:layout_marginBottom="@dimen/spacing_medium"
|
||||
android:text="@{song.album.name}"
|
||||
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
|
||||
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<color name="control_color">#202020</color>
|
||||
<color name="nav_color">#01fafafa</color>
|
||||
|
||||
<color name="background_black">#000000</color>
|
||||
<color name="selection_color_black">#343434</color>
|
||||
|
||||
<!--
|
||||
Base color set derived from Music Player GO.
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
<string name="setting_theme_day">Light</string>
|
||||
<string name="setting_theme_night">Dark</string>
|
||||
<string name="setting_accent">Accent</string>
|
||||
<string name="setting_black_mode">Black night theme</string>
|
||||
<string name="setting_black_mode_desc">Use a pure-black night theme</string>
|
||||
|
||||
<string name="setting_display">Display</string>
|
||||
<string name="setting_lib_display">Library Items</string>
|
||||
|
|
|
@ -36,4 +36,9 @@
|
|||
<item name="materialAlertDialogTheme">@style/Theme.CustomDialog</item>
|
||||
<!-- @formatter:on -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Base.Black" parent="Theme.Base">
|
||||
<item name="colorSurface">@color/background_black</item>
|
||||
<item name="colorControlHighlight">@color/selection_color_black</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -83,7 +83,7 @@
|
|||
<item name="colorSecondary">@color/brown</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Gray" parent="Theme.Base">
|
||||
<style name="Theme.Grey" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/grey</item>
|
||||
<item name="colorSecondary">@color/grey</item>
|
||||
</style>
|
||||
|
|
100
app/src/main/res/values/themes_black.xml
Normal file
100
app/src/main/res/values/themes_black.xml
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--
|
||||
All the base themes/accents for black mode.
|
||||
-->
|
||||
<style name="Theme.Red.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/red</item>
|
||||
<item name="colorSecondary">@color/red</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Pink.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/pink</item>
|
||||
<item name="colorSecondary">@color/pink</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Purple.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/purple</item>
|
||||
<item name="colorSecondary">@color/purple</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.DeepPurple.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/deep_purple</item>
|
||||
<item name="colorSecondary">@color/deep_purple</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Indigo.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/indigo</item>
|
||||
<item name="colorSecondary">@color/indigo</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Blue.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/blue</item>
|
||||
<item name="colorSecondary">@color/blue</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.LightBlue.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/light_blue</item>
|
||||
<item name="colorSecondary">@color/light_blue</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Cyan.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/cyan</item>
|
||||
<item name="colorSecondary">@color/cyan</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Teal.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/teal</item>
|
||||
<item name="colorSecondary">@color/teal</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Green.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/green</item>
|
||||
<item name="colorSecondary">@color/green</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.LightGreen.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/light_green</item>
|
||||
<item name="colorSecondary">@color/light_green</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Lime.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/lime</item>
|
||||
<item name="colorSecondary">@color/lime</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Yellow.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/yellow</item>
|
||||
<item name="colorSecondary">@color/yellow</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Orange.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/orange</item>
|
||||
<item name="colorSecondary">@color/orange</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.DeepOrange.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/deep_orange</item>
|
||||
<item name="colorSecondary">@color/deep_orange</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Brown.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/brown</item>
|
||||
<item name="colorSecondary">@color/brown</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Grey.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/grey</item>
|
||||
<item name="colorSecondary">@color/grey</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.BlueGrey.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/blue_grey</item>
|
||||
<item name="colorSecondary">@color/blue_grey</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Neutral.Black" parent="Theme.Base.Black">
|
||||
<item name="colorPrimary">@color/control_color</item>
|
||||
<item name="colorSecondary">@color/control_color</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -20,6 +20,14 @@
|
|||
app:summary="@string/color_label_blue"
|
||||
app:title="@string/setting_accent" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:defaultValue="true"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="KEY_BLACK_THEME"
|
||||
app:title="@string/setting_black_mode"
|
||||
app:summary="@string/setting_black_mode_desc"
|
||||
app:allowDividerBelow="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
|
Loading…
Reference in a new issue