Add theming system
Standardize theming across the app into ThemeUtils.
This commit is contained in:
parent
d5e6b813a9
commit
8f850f2288
13 changed files with 171 additions and 32 deletions
|
@ -10,7 +10,7 @@
|
|||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/BaseTheme">
|
||||
android:theme="@style/Theme.Base">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
@ -1,16 +1,27 @@
|
|||
package org.oxycblt.auxio
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import org.oxycblt.auxio.theme.accent
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
|
||||
setTheme(accent.second)
|
||||
|
||||
return super.onCreateView(name, context, attrs)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
// AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
|
||||
Log.d(this::class.simpleName, "Activity Created.")
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ import com.google.android.material.tabs.TabLayoutMediator
|
|||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||
import org.oxycblt.auxio.library.LibraryFragment
|
||||
import org.oxycblt.auxio.songs.SongsFragment
|
||||
import org.oxycblt.auxio.theme.getAccentTransparency
|
||||
import org.oxycblt.auxio.theme.getDeselectedTransparency
|
||||
import org.oxycblt.auxio.theme.accent
|
||||
import org.oxycblt.auxio.theme.getInactiveAlpha
|
||||
import org.oxycblt.auxio.theme.getTransparentAccent
|
||||
import org.oxycblt.auxio.theme.toColor
|
||||
|
||||
class MainFragment : Fragment() {
|
||||
|
@ -27,12 +28,14 @@ class MainFragment : Fragment() {
|
|||
private val songsFragment: SongsFragment by lazy { SongsFragment() }
|
||||
|
||||
private val colorSelected: Int by lazy {
|
||||
R.color.blue.toColor(requireContext())
|
||||
accent.first.toColor(requireContext())
|
||||
}
|
||||
|
||||
private val colorDeselected: Int by lazy {
|
||||
getAccentTransparency(
|
||||
requireContext(), R.color.blue, getDeselectedTransparency(R.color.blue)
|
||||
getTransparentAccent(
|
||||
requireContext(),
|
||||
accent.first,
|
||||
getInactiveAlpha(accent.first)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -83,10 +86,6 @@ class MainFragment : Fragment() {
|
|||
}
|
||||
)
|
||||
|
||||
binding.tabs.getTabAt(
|
||||
binding.viewPager.offscreenPageLimit
|
||||
)
|
||||
|
||||
Log.d(this::class.simpleName, "Fragment Created.")
|
||||
|
||||
return binding.root
|
||||
|
|
|
@ -4,8 +4,8 @@ import android.graphics.drawable.ColorDrawable
|
|||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.theme.getAccentTransparency
|
||||
import org.oxycblt.auxio.theme.getDayNightTransparency
|
||||
import org.oxycblt.auxio.theme.getDayNightAlpha
|
||||
import org.oxycblt.auxio.theme.getTransparentAccent
|
||||
|
||||
// Apply a custom vertical divider
|
||||
fun RecyclerView.applyDivider() {
|
||||
|
@ -16,8 +16,8 @@ fun RecyclerView.applyDivider() {
|
|||
|
||||
div.setDrawable(
|
||||
ColorDrawable(
|
||||
getAccentTransparency(
|
||||
context, R.color.divider_color, getDayNightTransparency()
|
||||
getTransparentAccent(
|
||||
context, R.color.divider_color, getDayNightAlpha()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -6,18 +6,43 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.graphics.ColorUtils
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
fun getDayNightTransparency(): Int {
|
||||
// Pairs of the base accent and its theme
|
||||
private val ACCENTS = listOf(
|
||||
Pair(R.color.red, R.style.Theme_Red),
|
||||
Pair(R.color.pink, R.style.Theme_Pink),
|
||||
Pair(R.color.purple, R.style.Theme_Purple),
|
||||
Pair(R.color.deep_purple, R.style.Theme_DeepPurple),
|
||||
Pair(R.color.indigo, R.style.Theme_Indigo),
|
||||
Pair(R.color.blue, R.style.Theme_Blue),
|
||||
Pair(R.color.light_blue, R.style.Theme_Blue),
|
||||
Pair(R.color.cyan, R.style.Theme_Cyan),
|
||||
Pair(R.color.teal, R.style.Theme_Teal),
|
||||
Pair(R.color.green, R.style.Theme_Green),
|
||||
Pair(R.color.light_green, R.style.Theme_LightGreen),
|
||||
Pair(R.color.lime, R.style.Theme_Lime),
|
||||
Pair(R.color.yellow, R.style.Theme_Yellow),
|
||||
Pair(R.color.amber, R.style.Theme_Amber),
|
||||
Pair(R.color.orange, R.style.Theme_Orange),
|
||||
Pair(R.color.deep_orange, R.style.Theme_DeepOrange),
|
||||
Pair(R.color.brown, R.style.Theme_Brown),
|
||||
Pair(R.color.grey, R.style.Theme_Gray),
|
||||
Pair(R.color.blue_grey, R.style.Theme_BlueGrey)
|
||||
)
|
||||
|
||||
val accent = ACCENTS[5]
|
||||
|
||||
fun getDayNightAlpha(): Int {
|
||||
val isDark = AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES
|
||||
|
||||
// Depending on the theme use a different opacity for the divider
|
||||
return if (isDark) 45 else 85
|
||||
}
|
||||
|
||||
fun getDeselectedTransparency(color: Int): Int {
|
||||
fun getInactiveAlpha(color: Int): Int {
|
||||
return if (color == R.color.yellow) 100 else 150
|
||||
}
|
||||
|
||||
fun getAccentTransparency(context: Context, color: Int, alpha: Int): Int {
|
||||
fun getTransparentAccent(context: Context, color: Int, alpha: Int): Int {
|
||||
return ColorUtils.setAlphaComponent(
|
||||
ContextCompat.getColor(context, color),
|
||||
alpha
|
||||
|
@ -28,6 +53,7 @@ fun Int.toColor(context: Context): Int {
|
|||
return try {
|
||||
ContextCompat.getColor(context, this)
|
||||
} catch (e: Exception) {
|
||||
ContextCompat.getColor(context, android.R.color.white)
|
||||
// Default to the emergency color [Black] if the loading fails.
|
||||
ContextCompat.getColor(context, android.R.color.black)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<shape android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="4dp" />
|
||||
<size android:height="2dp" />
|
||||
<size android:height="3dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -14,8 +14,7 @@
|
|||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:titleTextAppearance="@style/ToolbarStyle"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold"
|
||||
app:title="@string/title_library_fragment" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
android:id="@+id/loading_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateTint="@color/blue"
|
||||
android:indeterminateTint="?attr/colorPrimary"
|
||||
android:indeterminateTintMode="src_in"
|
||||
android:paddingBottom="@dimen/padding_tiny"
|
||||
app:layout_constraintBottom_toTopOf="@+id/error_text"
|
||||
|
@ -28,7 +28,8 @@
|
|||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:indeterminateTint="@color/blue" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error_text"
|
||||
|
@ -53,13 +54,14 @@
|
|||
android:text="@string/label_retry"
|
||||
android:visibility="gone"
|
||||
android:fontFamily="@font/inter_semibold"
|
||||
android:textColor="@color/blue"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/error_text"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible"
|
||||
tools:textColor="@color/blue" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
|
@ -20,6 +20,7 @@
|
|||
android:layout_height="@dimen/tab_menu_size"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:tabIndicatorColor="?android:attr/colorPrimary"
|
||||
app:tabGravity="fill"
|
||||
app:tabMode="fixed"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:titleTextAppearance="@style/ToolbarStyle"
|
||||
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:title="@string/title_all_songs" />
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<dimen name="cover_size_compact">44dp</dimen>
|
||||
<dimen name="cover_size_normal">56dp</dimen>
|
||||
|
||||
<dimen name="tab_menu_size">38dp</dimen>
|
||||
<dimen name="tab_menu_size">40dp</dimen>
|
||||
|
||||
<dimen name="elevation_normal">4dp</dimen>
|
||||
</resources>
|
|
@ -1,15 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Base theme -->
|
||||
<style name="BaseTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:colorPrimary">@color/blue</item>
|
||||
<style name="Theme.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:windowBackground">@color/background</item>
|
||||
<item name="android:statusBarColor">@android:color/black</item>
|
||||
<item name="android:fontFamily">@font/inter</item>
|
||||
</style>
|
||||
|
||||
<style name="ToolbarStyle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
|
||||
<style name="TextAppearance.Toolbar.Bold" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
|
||||
<item name="android:fontFamily">@font/inter_black</item>
|
||||
<item name="android:textColor">@color/blue</item>
|
||||
<item name="android:textColor">?android:attr/colorPrimary</item>
|
||||
</style>
|
||||
</resources>
|
102
app/src/main/res/values/themes.xml
Normal file
102
app/src/main/res/values/themes.xml
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Red" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/red</item>
|
||||
<item name="colorSecondary">@color/red</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Pink" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/pink</item>
|
||||
<item name="colorSecondary">@color/pink</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Purple" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/purple</item>
|
||||
<item name="colorSecondary">@color/purple</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.DeepPurple" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/deep_purple</item>
|
||||
<item name="colorSecondary">@color/deep_purple</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Indigo" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/indigo</item>
|
||||
<item name="colorSecondary">@color/indigo</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Blue" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/blue</item>
|
||||
<item name="colorSecondary">@color/blue</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.LightBlue" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/light_blue</item>
|
||||
<item name="colorSecondary">@color/light_blue</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.Cyan" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/cyan</item>
|
||||
<item name="colorSecondary">@color/cyan</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.Teal" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/teal</item>
|
||||
<item name="colorSecondary">@color/teal</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.Green" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/green</item>
|
||||
<item name="colorSecondary">@color/green</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.LightGreen" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/light_green</item>
|
||||
<item name="colorSecondary">@color/light_green</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Lime" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/lime</item>
|
||||
<item name="colorSecondary">@color/lime</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Yellow" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/yellow</item>
|
||||
<item name="colorSecondary">@color/yellow</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Amber" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/amber</item>
|
||||
<item name="colorSecondary">@color/amber</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Orange" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/orange</item>
|
||||
<item name="colorSecondary">@color/orange</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.DeepOrange" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/deep_orange</item>
|
||||
<item name="colorSecondary">@color/deep_orange</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Brown" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/brown</item>
|
||||
<item name="colorSecondary">@color/brown</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Gray" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/grey</item>
|
||||
<item name="colorSecondary">@color/grey</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.BlueGrey" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/blue_grey</item>
|
||||
<item name="colorSecondary">@color/blue_grey</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in a new issue