1
0
Fork 0

Styles for dark mode to match guidelines, closes

This commit is contained in:
Philipp Heckel 2022-02-07 18:35:36 -05:00
parent 678be49bff
commit e6c3a2e2bd
15 changed files with 140 additions and 52 deletions

View file

@ -12,6 +12,7 @@ import io.heckel.ntfy.R
import io.heckel.ntfy.db.* import io.heckel.ntfy.db.*
import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.log.Log import io.heckel.ntfy.log.Log
import io.heckel.ntfy.ui.Colors
import io.heckel.ntfy.ui.DetailActivity import io.heckel.ntfy.ui.DetailActivity
import io.heckel.ntfy.ui.MainActivity import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.* import io.heckel.ntfy.util.*
@ -52,7 +53,7 @@ class NotificationService(val context: Context) {
val channelId = toChannelId(notification.priority) val channelId = toChannelId(notification.priority)
val builder = NotificationCompat.Builder(context, channelId) val builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setColor(ContextCompat.getColor(context, R.color.primaryColor)) .setColor(ContextCompat.getColor(context, Colors.notificationIcon))
.setContentTitle(title) .setContentTitle(title)
.setOnlyAlertOnce(true) // Do not vibrate or play sound if already showing (updates!) .setOnlyAlertOnce(true) // Do not vibrate or play sound if already showing (updates!)
.setAutoCancel(true) // Cancel when notification is clicked .setAutoCancel(true) // Cancel when notification is clicked

View file

@ -19,6 +19,7 @@ import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.log.Log import io.heckel.ntfy.log.Log
import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationDispatcher import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.ui.Colors
import io.heckel.ntfy.ui.MainActivity import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.topicUrl import io.heckel.ntfy.util.topicUrl
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -292,7 +293,7 @@ class SubscriberService : Service() {
} }
return NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) return NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_instant) .setSmallIcon(R.drawable.ic_notification_instant)
.setColor(ContextCompat.getColor(this, R.color.primaryColor)) .setColor(ContextCompat.getColor(this, Colors.notificationIcon))
.setContentTitle(title) .setContentTitle(title)
.setContentText(text) .setContentText(text)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)

View file

@ -0,0 +1,28 @@
package io.heckel.ntfy.ui
import android.content.Context
import io.heckel.ntfy.R
import io.heckel.ntfy.util.isDarkThemeOn
class Colors {
companion object {
const val refreshProgressIndicator = R.color.teal
const val notificationIcon = R.color.teal
fun itemSelectedBackground(context: Context): Int {
return if (isDarkThemeOn(context)) R.color.gray_dark else R.color.gray_light
}
fun statusBarNormal(context: Context): Int {
return if (isDarkThemeOn(context)) R.color.black_light else R.color.teal
}
fun statusBarActionMode(context: Context): Int {
return if (isDarkThemeOn(context)) R.color.black_light else R.color.teal_dark
}
fun dangerText(context: Context): Int {
return if (isDarkThemeOn(context)) R.color.red_light else R.color.red_dark
}
}
}

View file

@ -106,7 +106,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
// Swipe to refresh // Swipe to refresh
mainListContainer = findViewById(R.id.detail_notification_list_container) mainListContainer = findViewById(R.id.detail_notification_list_container)
mainListContainer.setOnRefreshListener { refresh() } mainListContainer.setOnRefreshListener { refresh() }
mainListContainer.setColorSchemeResources(R.color.primaryColor) mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator)
// Update main list based on viewModel (& its datasource/livedata) // Update main list based on viewModel (& its datasource/livedata)
val noEntriesText: View = findViewById(R.id.detail_no_notifications) val noEntriesText: View = findViewById(R.id.detail_no_notifications)
@ -477,7 +477,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
dialog.setOnShowListener { dialog.setOnShowListener {
dialog dialog
.getButton(AlertDialog.BUTTON_POSITIVE) .getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor)) .setTextAppearance(R.style.DangerText)
} }
dialog.show() dialog.show()
} }
@ -512,7 +512,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
dialog.setOnShowListener { dialog.setOnShowListener {
dialog dialog
.getButton(AlertDialog.BUTTON_POSITIVE) .getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor)) .setTextAppearance(R.style.DangerText)
} }
dialog.show() dialog.show()
} }
@ -619,7 +619,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
dialog.setOnShowListener { dialog.setOnShowListener {
dialog dialog
.getButton(AlertDialog.BUTTON_POSITIVE) .getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor)) .setTextAppearance(R.style.DangerText)
} }
dialog.show() dialog.show()
} }
@ -634,8 +634,8 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
redrawList() redrawList()
// Fade status bar color // Fade status bar color
val fromColor = ContextCompat.getColor(this, R.color.primaryColor) val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this))
val toColor = ContextCompat.getColor(this, R.color.primaryDarkColor) val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this))
fadeStatusBarColor(window, fromColor, toColor) fadeStatusBarColor(window, fromColor, toColor)
} }
@ -650,8 +650,8 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
redrawList() redrawList()
// Fade status bar color // Fade status bar color
val fromColor = ContextCompat.getColor(this, R.color.primaryDarkColor) val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this))
val toColor = ContextCompat.getColor(this, R.color.primaryColor) val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this))
fadeStatusBarColor(window, fromColor, toColor) fadeStatusBarColor(window, fromColor, toColor)
} }

View file

@ -96,8 +96,7 @@ class DetailAdapter(private val activity: Activity, private val repository: Repo
tagsView.visibility = View.GONE tagsView.visibility = View.GONE
} }
if (selected.contains(notification.id)) { if (selected.contains(notification.id)) {
val backgroundColor = if (isDarkThemeOn(context, repository)) R.color.primaryDarkSelectedRowColor else R.color.primaryLightSelectedRowColor itemView.setBackgroundResource(Colors.itemSelectedBackground(context))
itemView.setBackgroundResource(backgroundColor);
} }
renderPriority(context, notification) renderPriority(context, notification)
maybeRenderAttachment(context, notification) maybeRenderAttachment(context, notification)

View file

@ -23,6 +23,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.work.* import androidx.work.*
import com.google.android.material.floatingactionbutton.FloatingActionButton
import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application import io.heckel.ntfy.app.Application
@ -56,7 +57,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
private lateinit var mainList: RecyclerView private lateinit var mainList: RecyclerView
private lateinit var mainListContainer: SwipeRefreshLayout private lateinit var mainListContainer: SwipeRefreshLayout
private lateinit var adapter: MainAdapter private lateinit var adapter: MainAdapter
private lateinit var fab: View private lateinit var fab: FloatingActionButton
// Other stuff // Other stuff
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
@ -88,7 +89,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
// Swipe to refresh // Swipe to refresh
mainListContainer = findViewById(R.id.main_subscriptions_list_container) mainListContainer = findViewById(R.id.main_subscriptions_list_container)
mainListContainer.setOnRefreshListener { refreshAllSubscriptions() } mainListContainer.setOnRefreshListener { refreshAllSubscriptions() }
mainListContainer.setColorSchemeResources(R.color.primaryColor) mainListContainer.setColorSchemeResources(Colors.refreshProgressIndicator)
// Update main list based on viewModel (& its datasource/livedata) // Update main list based on viewModel (& its datasource/livedata)
val noEntries: View = findViewById(R.id.main_no_subscriptions) val noEntries: View = findViewById(R.id.main_no_subscriptions)
@ -512,7 +513,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
dialog.setOnShowListener { dialog.setOnShowListener {
dialog dialog
.getButton(AlertDialog.BUTTON_POSITIVE) .getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor)) .setTextAppearance(R.style.DangerText)
} }
dialog.show() dialog.show()
} }
@ -539,8 +540,8 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
}) })
// Fade status bar color // Fade status bar color
val fromColor = ContextCompat.getColor(this, R.color.primaryColor) val fromColor = ContextCompat.getColor(this, Colors.statusBarNormal(this))
val toColor = ContextCompat.getColor(this, R.color.primaryDarkColor) val toColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this))
fadeStatusBarColor(window, fromColor, toColor) fadeStatusBarColor(window, fromColor, toColor)
} }
@ -568,8 +569,8 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
}) })
// Fade status bar color // Fade status bar color
val fromColor = ContextCompat.getColor(this, R.color.primaryDarkColor) val fromColor = ContextCompat.getColor(this, Colors.statusBarActionMode(this))
val toColor = ContextCompat.getColor(this, R.color.primaryColor) val toColor = ContextCompat.getColor(this, Colors.statusBarNormal(this))
fadeStatusBarColor(window, fromColor, toColor) fadeStatusBarColor(window, fromColor, toColor)
} }

View file

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatDelegate
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -102,8 +101,7 @@ class MainAdapter(private val repository: Repository, private val onClick: (Subs
itemView.setOnClickListener { onClick(subscription) } itemView.setOnClickListener { onClick(subscription) }
itemView.setOnLongClickListener { onLongClick(subscription); true } itemView.setOnLongClickListener { onLongClick(subscription); true }
if (selected.contains(subscription.id)) { if (selected.contains(subscription.id)) {
val backgroundColor = if (isDarkThemeOn(context, repository)) R.color.primaryDarkSelectedRowColor else R.color.primaryLightSelectedRowColor itemView.setBackgroundResource(Colors.itemSelectedBackground(context))
itemView.setBackgroundResource(backgroundColor)
} }
} }
} }

View file

@ -3,6 +3,7 @@ package io.heckel.ntfy.ui
import android.app.AlertDialog import android.app.AlertDialog
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
@ -15,7 +16,6 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import io.heckel.ntfy.R import io.heckel.ntfy.R
import io.heckel.ntfy.db.User import io.heckel.ntfy.db.User
import kotlin.random.Random
class UserFragment : DialogFragment() { class UserFragment : DialogFragment() {
private var user: User? = null private var user: User? = null
@ -97,9 +97,15 @@ class UserFragment : DialogFragment() {
// Delete button should be red // Delete button should be red
if (user != null) { if (user != null) {
dialog if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
.getButton(AlertDialog.BUTTON_NEUTRAL) dialog
.setTextColor(ContextCompat.getColor(requireContext(), R.color.primaryDangerButtonColor)) .getButton(AlertDialog.BUTTON_NEUTRAL)
.setTextAppearance(R.style.DangerText)
} else {
dialog
.getButton(AlertDialog.BUTTON_NEUTRAL)
.setTextColor(ContextCompat.getColor(requireContext(), Colors.dangerText(requireContext())))
}
} }
// Validate input when typing // Validate input when typing

View file

@ -3,17 +3,14 @@ package io.heckel.ntfy.util
import android.animation.ArgbEvaluator import android.animation.ArgbEvaluator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.PowerManager import android.os.PowerManager
import android.provider.OpenableColumns import android.provider.OpenableColumns
import android.provider.Settings
import android.view.Window import android.view.Window
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Notification import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription import io.heckel.ntfy.db.Subscription
@ -206,17 +203,17 @@ fun isIgnoringBatteryOptimizations(context: Context): Boolean {
} }
// Returns true if dark mode is on, see https://stackoverflow.com/a/60761189/1440785 // Returns true if dark mode is on, see https://stackoverflow.com/a/60761189/1440785
fun Context.isDarkThemeOn(): Boolean { fun Context.systemDarkThemeOn(): Boolean {
return resources.configuration.uiMode and return resources.configuration.uiMode and
Configuration.UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES Configuration.UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES
} }
fun isDarkThemeOn(context: Context, repository: Repository): Boolean { fun isDarkThemeOn(context: Context): Boolean {
val darkMode = repository.getDarkMode() val darkMode = Repository.getInstance(context).getDarkMode()
if (darkMode == AppCompatDelegate.MODE_NIGHT_YES) { if (darkMode == AppCompatDelegate.MODE_NIGHT_YES) {
return true return true
} }
if (darkMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && context.isDarkThemeOn()) { if (darkMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && context.systemDarkThemeOn()) {
return true return true
} }
return false return false

View file

@ -139,11 +139,12 @@
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="24dp"
android:contentDescription="@string/main_add_button_description" android:contentDescription="@string/main_add_button_description"
android:src="@drawable/ic_add_black_24dp" android:src="@drawable/ic_add_black_24dp"
app:tint="@color/primaryLightTextColor"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:backgroundTint="@color/primaryColor"/> app:layout_constraintEnd_toEndOf="parent"
style="@style/FloatingActionButton"
/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -139,7 +139,12 @@
android:layout_height="wrap_content" android:id="@+id/add_dialog_subscribe_error_text" android:layout_height="wrap_content" android:id="@+id/add_dialog_subscribe_error_text"
android:paddingStart="4dp" android:paddingStart="4dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/add_dialog_subscribe_instant_delivery_description" android:paddingEnd="4dp" android:textColor="@color/primaryDangerButtonColor" app:layout_constraintStart_toEndOf="@id/add_dialog_subscribe_error_text_image" android:layout_marginTop="5dp" tools:visibility="gone"/> app:layout_constraintTop_toBottomOf="@id/add_dialog_subscribe_instant_delivery_description"
android:paddingEnd="4dp"
android:textAppearance="@style/DangerText"
app:layout_constraintStart_toEndOf="@id/add_dialog_subscribe_error_text_image"
android:layout_marginTop="5dp"
tools:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </ScrollView>
<ScrollView <ScrollView
@ -197,7 +202,10 @@
android:layout_height="wrap_content" android:id="@+id/add_dialog_login_error_text" android:layout_height="wrap_content" android:id="@+id/add_dialog_login_error_text"
android:paddingStart="4dp" android:paddingStart="4dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/add_dialog_login_password" android:paddingEnd="4dp" android:textColor="@color/primaryDangerButtonColor" app:layout_constraintStart_toEndOf="@id/add_dialog_login_error_text_image"/> app:layout_constraintTop_toBottomOf="@id/add_dialog_login_password"
android:paddingEnd="4dp"
android:textAppearance="@style/DangerText"
app:layout_constraintStart_toEndOf="@id/add_dialog_login_error_text_image"/>
<ProgressBar <ProgressBar
style="?android:attr/progressBarStyle" style="?android:attr/progressBarStyle"
android:layout_width="25dp" android:layout_width="25dp"

View file

@ -0,0 +1,33 @@
<resources>
<!--
This file contains only overrides for the dark theme.
Also see "ui/Colors.kt" for colors that have to be defined in code.
Resources:
- https://material.io/design/color/dark-theme.html
- https://material.io/develop/android/theming/dark
- https://developer.android.com/codelabs/basic-android-kotlin-training-change-app-theme#4
- https://developer.android.com/guide/topics/ui/look-and-feel/themes
-->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/teal_light</item>
<item name="colorAccent">@color/teal_light</item> <!-- checkboxes, text fields -->
<item name="android:colorBackground">@color/black_light</item> <!-- background -->
<item name="android:statusBarColor">@color/black_light</item>
<item name="actionModeBackground">@color/black_light</item>
<!-- Action bar background & text color -->
<item name="colorSurface">@color/gray_dark</item>
<item name="colorOnSurface">@color/white</item>
</style>
<style name="DangerText" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/red_light</item>
</style>
<style name="FloatingActionButton" parent="@style/Widget.MaterialComponents.FloatingActionButton">
<item name="tint">@color/black_light</item>
<item name="backgroundTint">@color/teal_light</item>
</style>
</resources>

View file

@ -1,13 +1,16 @@
<!--?xml version="1.0" encoding="UTF-8"?--> <!--?xml version="1.0" encoding="UTF-8"?-->
<resources> <resources>
<color name="primaryColor">#338574</color> <color name="black">#ff000000</color>
<color name="primaryDangerButtonColor">#C30000</color> <color name="black_light">#121212</color> <!-- Main dark mode surface color, as per style guide -->
<color name="white">#ffffffff</color>
<color name="primaryLightColor">#338574</color> <color name="teal">#338574</color> <!-- Primary color (light mode) -->
<color name="primaryLightTextColor">#FFFFFF</color> <color name="teal_light">#65b5a3</color> <!-- Primary color (dark mode) -->
<color name="primaryLightSelectedRowColor">#EEEEEE</color> <color name="teal_dark">#2a6e60</color> <!-- Action bar background in action mode (light mode) -->
<color name="red_light">#fe4d2e</color> <!-- Danger text (dark mode) -->
<color name="red_dark">#c30000</color> <!-- Danger text (light mode) -->
<color name="primaryDarkColor">#2A6E60</color> <color name="gray_light">#eeeeee</color> <!-- Light theme item selection -->
<color name="primaryDarkSelectedRowColor">#444444</color> <color name="gray_dark">#282828</color> <!-- Dark mode action bar & item selection -->
</resources> </resources>

View file

@ -188,8 +188,8 @@
<string name="notification_dialog_cancel">Cancel</string> <string name="notification_dialog_cancel">Cancel</string>
<string name="notification_dialog_save">Save</string> <string name="notification_dialog_save">Save</string>
<string name="notification_dialog_enabled_toast_message">Notifications re-enabled</string> <string name="notification_dialog_enabled_toast_message">Notifications re-enabled</string>
<string name="notification_dialog_muted_forever_toast_message">Notifications are now paused</string> <string name="notification_dialog_muted_forever_toast_message">Notifications paused</string>
<string name="notification_dialog_muted_until_toast_message">Notifications are paused until %1$s</string> <string name="notification_dialog_muted_until_toast_message">Notifications paused until %1$s</string>
<string name="notification_dialog_show_all">Show all notifications</string> <string name="notification_dialog_show_all">Show all notifications</string>
<string name="notification_dialog_30min">30 minutes</string> <string name="notification_dialog_30min">30 minutes</string>
<string name="notification_dialog_1h">1 hour</string> <string name="notification_dialog_1h">1 hour</string>

View file

@ -1,10 +1,22 @@
<resources> <resources>
<!-- DayNight mode for easy dark mode, see https://material.io/develop/android/theming/dark --> <!-- Main app theme; dark theme styles see values-night/styles.xml -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/primaryColor</item> <item name="colorPrimary">@color/teal</item>
<item name="colorAccent">@color/primaryLightColor</item> <item name="colorAccent">@color/teal</item> <!-- checkboxes, text fields -->
<item name="android:statusBarColor">@color/primaryColor</item> <item name="android:colorBackground">@color/white</item> <!-- background -->
<item name="actionModeBackground">@color/primaryDarkColor</item> <item name="android:statusBarColor">@color/teal</item>
<item name="actionModeBackground">@color/teal_dark</item>
</style>
<!-- Danger buttons & text -->
<style name="DangerText" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/red_dark</item>
</style>
<!-- Floating action button -->
<style name="FloatingActionButton" parent="@style/Widget.MaterialComponents.FloatingActionButton">
<item name="tint">@color/white</item>
<item name="backgroundTint">@color/teal</item>
</style> </style>
<!-- Rounded corners in images, see https://stackoverflow.com/a/61960983/1440785 --> <!-- Rounded corners in images, see https://stackoverflow.com/a/61960983/1440785 -->