Add basic theme switching

This commit is contained in:
Phillip Thelen 2019-08-07 09:14:11 +02:00
parent 2e7f26adbb
commit 2b77acc593
12 changed files with 193 additions and 67 deletions

View file

@ -23,7 +23,7 @@
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:theme="@style/MainAppTheme"
tools:replace="android:name"
android:fullBackupContent="@xml/backup_descriptor"
android:configChanges="orientation"
@ -34,7 +34,7 @@
<activity
android:name=".ui.activities.MainActivity"
android:label="@string/app_name"
android:theme="@style/MainAppTheme"
android:theme="@style/LaunchAppTheme"
android:windowSoftInputMode="stateHidden|adjustResize">
<nav-graph android:value="@navigation/navigation" />
<intent-filter>
@ -80,12 +80,10 @@
<activity
android:name=".ui.activities.LoginActivity"
android:label="@string/LoginActivityName"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".ui.activities.IntroActivity"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
@ -114,8 +112,7 @@
android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
android:value="false"/>
<activity
android:name=".ui.activities.AboutActivity"
android:theme="@style/AppThemeWithActionBarBlackText"/>
android:name=".ui.activities.AboutActivity" />
<activity
android:name=".ui.activities.TaskFormActivity"
android:parentActivityName=".ui.activities.MainActivity"
@ -127,7 +124,6 @@
</activity>
<activity
android:name=".ui.activities.GroupFormActivity"
android:theme="@style/AppTheme.NoActionBar"
android:parentActivityName=".ui.activities.MainActivity"
tools:ignore="UnusedAttribute">
<meta-data
@ -145,12 +141,10 @@
</activity>
<activity
android:name=".ui.activities.GroupInviteActivity"
android:theme="@style/AppThemeWithActionBarBlackText"
tools:ignore="UnusedAttribute">
</activity>
<activity
android:name=".ui.activities.FullProfileActivity"
android:theme="@style/AppThemeWithActionBarBlackText"
android:parentActivityName=".ui.activities.MainActivity"
tools:ignore="UnusedAttribute">
<meta-data
@ -167,7 +161,6 @@
</activity>
<activity
android:name=".ui.activities.ChallengeFormActivity"
android:theme="@style/AppTheme.ActionBar"
android:parentActivityName=".ui.activities.MainActivity"
android:launchMode="singleTask"
tools:ignore="UnusedAttribute">

View file

@ -8,6 +8,7 @@
<attr name="textColorPrimary" format="color" />
<attr name="textColorSecondary" format="color" />
<attr name="textColorPrimaryDark" format="color" />
<attr name="barColor" format="color" />
<attr name="textColorSecondaryDark" format="color" />
<attr name="statsColor" format="color" />
<attr name="statsTitle" format="string" />

View file

@ -15,16 +15,20 @@
<color name="maroon_100">#DE3F3F</color>
<color name="maroon_50">#C92B2B</color>
<color name="maroon_10">#B01515</color>
<color name="maroon_5">#7D0C0C</color>
<color name="red_500">#ffb6b8</color>
<color name="red_100">#FF6165</color>
<color name="red_50">#F74E52</color>
<color name="red_10">#F23035</color>
<color name="red_5">#BF262B</color>
<color name="red_1">#8C1C20</color>
<color name="orange_500">#ffc8a7</color>
<color name="orange_100">#FF944C</color>
<color name="orange_50">#FA8537</color>
<color name="orange_10">#F47825</color>
<color name="orange_5">#A85219</color>
<color name="yellow_500">#fedead</color>
<color name="yellow_100">#FFBE5D</color>
@ -42,6 +46,7 @@
<color name="teal_100">#3BCAD7</color>
<color name="teal_50">#34B5C1</color>
<color name="teal_10">#26A0AB</color>
<color name="teal_5">#1A7078</color>
<color name="blue_500">#a9dcf6</color>
<color name="blue_100">#50B5E9</color>

View file

@ -943,4 +943,5 @@
<string name="create_task">Create %s</string>
<string name="details">Details</string>
<string name="share_challenge_with">Share Challenge with</string>
<string name="app_theme">App Theme</string>
</resources>

View file

@ -30,6 +30,7 @@
<item name="textColorSecondary">@color/gray_200</item>
<item name="textColorPrimaryDark">#D5C8FF</item>
<item name="textColorSecondaryDark">@color/brand_500</item>
<item name="barColor">@color/brand_100</item>
<item name="colorContentBackground">@color/white</item>
<item name="colorWindowBackground">@color/gray_700</item>
@ -41,8 +42,106 @@
<item name="android:textColorLink">@color/brand_400</item>
<item name="alertDialogTheme">@style/AlertDialogTheme</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:statusBarColor">@color/brand_50</item>
<item name="android:navigationBarColor">@color/brand_50</item>
</style>
<style name="MainAppTheme.Green">
<item name="colorPrimary">@color/green_10</item>
<item name="colorPrimaryDark">@color/green_5</item>
<item name="colorAccent">@color/green_100</item>
<item name="android:colorPrimary">@color/green_10</item>
<item name="android:colorPrimaryDark">@color/green_5</item>
<item name="android:colorAccent">@color/green_100</item>
<item name="colorPrimaryOffset">@color/green_50</item>
<item name="colorPrimaryDistinct">@color/green_500</item>
<item name="colorBadgeBackground">@color/green_100</item>
<item name="textColorSecondaryDark">@color/green_500</item>
<item name="android:textColorLink">@color/green_100</item>
<item name="textColorPrimaryDark">@color/green_500</item>
<item name="barColor">@color/green_10</item>
</style>
<style name="MainAppTheme.Blue">
<item name="colorPrimary">@color/blue_10</item>
<item name="colorPrimaryDark">@color/blue_5</item>
<item name="colorAccent">@color/blue_100</item>
<item name="android:colorPrimary">@color/blue_10</item>
<item name="android:colorPrimaryDark">@color/blue_5</item>
<item name="android:colorAccent">@color/blue_100</item>
<item name="colorPrimaryOffset">@color/blue_50</item>
<item name="colorPrimaryDistinct">@color/blue_500</item>
<item name="colorBadgeBackground">@color/blue_100</item>
<item name="textColorSecondaryDark">@color/blue_500</item>
<item name="android:textColorLink">@color/blue_100</item>
<item name="textColorPrimaryDark">@color/blue_500</item>
<item name="barColor">@color/blue_10</item>
</style>
<style name="MainAppTheme.Red">
<item name="colorPrimary">@color/red_5</item>
<item name="colorPrimaryDark">@color/red_1</item>
<item name="colorAccent">@color/red_100</item>
<item name="android:colorPrimary">@color/red_5</item>
<item name="android:colorPrimaryDark">@color/red_1</item>
<item name="android:colorAccent">@color/red_100</item>
<item name="colorPrimaryOffset">@color/red_10</item>
<item name="colorPrimaryDistinct">@color/red_500</item>
<item name="colorBadgeBackground">@color/red_100</item>
<item name="textColorSecondaryDark">@color/red_500</item>
<item name="android:textColorLink">@color/red_100</item>
<item name="textColorPrimaryDark">@color/red_500</item>
<item name="barColor">@color/red_5</item>
</style>
<style name="MainAppTheme.Maroon">
<item name="colorPrimary">@color/maroon_10</item>
<item name="colorPrimaryDark">@color/maroon_5</item>
<item name="colorAccent">@color/maroon_100</item>
<item name="android:colorPrimary">@color/maroon_10</item>
<item name="android:colorPrimaryDark">@color/maroon_5</item>
<item name="android:colorAccent">@color/maroon_100</item>
<item name="colorPrimaryOffset">@color/maroon_50</item>
<item name="colorPrimaryDistinct">@color/maroon_500</item>
<item name="colorBadgeBackground">@color/maroon_100</item>
<item name="textColorSecondaryDark">@color/maroon_500</item>
<item name="android:textColorLink">@color/maroon_100</item>
<item name="textColorPrimaryDark">@color/maroon_500</item>
<item name="barColor">@color/maroon_10</item>
</style>
<style name="MainAppTheme.Teal">
<item name="colorPrimary">@color/teal_10</item>
<item name="colorPrimaryDark">@color/teal_5</item>
<item name="colorAccent">@color/teal_100</item>
<item name="android:colorPrimary">@color/teal_10</item>
<item name="android:colorPrimaryDark">@color/teal_5</item>
<item name="android:colorAccent">@color/teal_100</item>
<item name="colorPrimaryOffset">@color/teal_50</item>
<item name="colorPrimaryDistinct">@color/teal_500</item>
<item name="colorBadgeBackground">@color/teal_100</item>
<item name="textColorSecondaryDark">@color/teal_500</item>
<item name="android:textColorLink">@color/teal_100</item>
<item name="textColorPrimaryDark">@color/teal_500</item>
<item name="barColor">@color/teal_10</item>
</style>
<style name="MainAppTheme.Orange">
<item name="colorPrimary">@color/orange_10</item>
<item name="colorPrimaryDark">@color/orange_5</item>
<item name="colorAccent">@color/orange_100</item>
<item name="android:colorPrimary">@color/orange_10</item>
<item name="android:colorPrimaryDark">@color/orange_5</item>
<item name="android:colorAccent">@color/orange_100</item>
<item name="colorPrimaryOffset">@color/orange_50</item>
<item name="colorPrimaryDistinct">@color/orange_500</item>
<item name="colorBadgeBackground">@color/orange_100</item>
<item name="textColorSecondaryDark">@color/orange_500</item>
<item name="android:textColorLink">@color/orange_100</item>
<item name="textColorPrimaryDark">@color/orange_500</item>
<item name="barColor">@color/orange_10</item>
</style>
<style name="BottomSheetTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">false</item>
@ -55,63 +154,13 @@
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="AppTheme.ActionBar" parent="AppTheme">
<item name="windowActionBar">true</item>
<item name="windowNoTitle">false</item>
</style>
<style name="AppTheme.ActionBar.Transparent" parent="AppTheme.ActionBar">
<item name="actionBarStyle">@style/ActionBarTransparent</item>
<item name="android:statusBarColor">@color/brand_50</item>
<item name="android:navigationBarColor">@color/brand_50</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="ActionBarTransparent">
<item name="android:background">@color/transparent</item>
</style>
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@color/brand_50</item>
<item name="android:navigationBarColor">@color/brand_50</item>
</style>
<style name="MainAppTheme" parent="AppTheme.NoActionBar">
<style name="LaunchAppTheme" parent="AppTheme">
<item name="android:windowBackground">@drawable/activity_launch_background</item>
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:fitsSystemWindows">false</item>
</style>
<style name="AppTheme.NoActionBar.Green">
<item name="colorPrimary">@color/green_10</item>
<item name="colorPrimaryDark">@color/green_5</item>
<item name="colorAccent">@color/green_100</item>
<item name="colorPrimaryOffset">@color/green_50</item>
<item name="colorPrimaryDistinct">@color/green_500</item>
<item name="colorBadgeBackground">@color/green_100</item>
<item name="textColorSecondaryDark">@color/green_500</item>
<item name="android:textColorLink">@color/green_100</item>
<style name="MainAppTheme" parent="AppTheme">
</style>
<style name="AppTheme.NoActionBar.Blue">
<item name="colorPrimary">@color/blue_10</item>
<item name="colorPrimaryDark">@color/blue_5</item>
<item name="colorAccent">@color/blue_100</item>
<item name="colorPrimaryOffset">@color/blue_50</item>
<item name="colorPrimaryDistinct">@color/blue_500</item>
<item name="colorBadgeBackground">@color/blue_100</item>
<item name="textColorSecondaryDark">@color/blue_500</item>
<item name="android:textColorLink">@color/blue_100</item>
</style>
<style name="AppThemeWithActionBarBlackText" parent="AppTheme.ActionBar">
<item name="android:textColorPrimary">@android:color/black</item>
</style>
<style name="PopupTheme" parent="Widget.AppCompat.Light.PopupMenu">
<item name="android:popupBackground">@android:color/white</item>

View file

@ -126,6 +126,27 @@
<item>airuTheme</item>
</string-array>
<string-array name="AppThemes">
<item>Default</item>
<item>Maroon</item>
<item>Red</item>
<item>Orange</item>
<item>Green</item>
<item>Teal</item>
<item>Blue</item>
</string-array>
<string-array name="AppThemeValues">
<item>purple</item>
<item>maroon</item>
<item>red</item>
<item>orange</item>
<item>green</item>
<item>teal</item>
<item>blue</item>
</string-array>
<string-array name="server_urls">
<item>https://habitica.com</item>
<item>https://habitrpg-staging.herokuapp.com</item>

View file

@ -132,6 +132,11 @@
android:entryValues="@array/AudioValues"
android:summary="@string/AudioTheme_summary"
android:layout="@layout/preference_child_summary"/>
<ListPreference android:title="@string/app_theme"
android:key="theme_name"
android:entries="@array/AppThemes"
android:entryValues="@array/AppThemeValues"
android:layout="@layout/preference_child_summary"/>
<CheckBoxPreference android:title="@string/dailyDueDefaultView"
android:key="dailyDueDefaultView"
android:summary="@string/dailyDueDefaultViewDescription"

View file

@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.ui.activities
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Bundle
import android.preference.PreferenceManager
@ -8,8 +9,10 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.Toolbar
import com.habitrpg.android.habitica.HabiticaApplication
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.events.ShowConnectionProblemEvent
import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.helpers.LanguageHelper
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import io.reactivex.disposables.CompositeDisposable
@ -20,6 +23,7 @@ import java.util.*
abstract class BaseActivity : AppCompatActivity() {
private var currentTheme: String? = null
private var destroyed: Boolean = false
protected abstract fun getLayoutResId(): Int
@ -42,6 +46,7 @@ abstract class BaseActivity : AppCompatActivity() {
val configuration = Configuration()
configuration.setLocale(languageHelper.locale)
resources.updateConfiguration(configuration, resources.displayMetrics)
loadTheme(sharedPreferences)
delegate.setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO)
super.onCreate(savedInstanceState)
@ -59,6 +64,7 @@ abstract class BaseActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
isActivityVisible = true
loadTheme(PreferenceManager.getDefaultSharedPreferences(this))
}
override fun onPause() {
@ -73,6 +79,28 @@ abstract class BaseActivity : AppCompatActivity() {
super.onStop()
}
private fun loadTheme(sharedPreferences: SharedPreferences) {
val theme = sharedPreferences.getString("theme_name", "purple")
if (theme == currentTheme) return
setTheme(when (theme) {
"maroon" -> R.style.MainAppTheme_Maroon
"red" -> R.style.MainAppTheme_Red
"orange" -> R.style.MainAppTheme_Orange
"green" -> R.style.MainAppTheme_Green
"teal" -> R.style.MainAppTheme_Teal
"blue" -> R.style.MainAppTheme_Blue
else -> R.style.MainAppTheme
})
window.navigationBarColor = getThemeColor(R.attr.colorPrimaryDark)
window.statusBarColor = getThemeColor(R.attr.colorPrimaryDark)
if (currentTheme != null) {
reload()
} else {
currentTheme = theme
}
}
protected abstract fun injectActivity(component: UserComponent?)
protected fun setupToolbar(toolbar: Toolbar?) {
@ -107,4 +135,10 @@ abstract class BaseActivity : AppCompatActivity() {
alert.addButton(android.R.string.ok, true, false, null)
alert.show()
}
fun reload() {
finish()
overridePendingTransition(R.anim.activity_fade_in, R.anim.activity_fade_out)
startActivity(intent)
}
}

View file

@ -165,10 +165,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
launchTrace = FirebasePerformance.getInstance().newTrace("MainActivityLaunch")
launchTrace?.start()
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
sharedPreferences.edit {
this.putInt("theme", R.style.AppTheme_NoActionBar)
}
super.onCreate(savedInstanceState)
if (!HabiticaBaseApplication.checkUserAuthentication(this, hostConfig)) {

View file

@ -11,6 +11,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ApiClient
@ -23,6 +24,7 @@ import com.habitrpg.android.habitica.prefs.TimePreference
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity
import com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.android.habitica.ui.activities.PrefsActivity
import io.reactivex.functions.Consumer
import java.util.*
import javax.inject.Inject
@ -68,6 +70,9 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
serverUrlPreference = findPreference("server_url") as? ListPreference
serverUrlPreference?.isVisible = false
serverUrlPreference?.summary = preferenceManager.sharedPreferences.getString("server_url", "")
val themePreference = findPreference("theme_name") as? ListPreference
themePreference?.isVisible = configManager.testingLevel() == AppTestingLevel.ALPHA || BuildConfig.DEBUG
themePreference?.summary = preferenceManager.sharedPreferences.getString("theme_name", "")
}
override fun onResume() {
@ -200,6 +205,10 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
soundManager.preloadAllFiles()
}
}
"theme_name" -> {
val activity = activity as? PrefsActivity ?: return
activity.reload()
}
"dailyDueDefaultView" -> userRepository.updateUser(user, "preferences.dailyDueDefaultView", sharedPreferences.getBoolean(key, false))
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
"server_url" -> {

View file

@ -9,6 +9,7 @@ import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.ui.helpers.bindView
@ -31,7 +32,7 @@ class BottomNavigationItem @JvmOverloads constructor(
} else {
selectedTitleView.visibility = View.GONE
titleView.visibility = View.VISIBLE
iconView.drawable.setColorFilter(ContextCompat.getColor(context, R.color.brand_500), PorterDuff.Mode.MULTIPLY )
iconView.drawable.setColorFilter(context.getThemeColor(R.attr.textColorPrimaryDark), PorterDuff.Mode.MULTIPLY )
}
}

View file

@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.ui.views.navigation
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.PorterDuff
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewGroup
@ -10,11 +11,13 @@ import android.view.animation.BounceInterpolator
import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.core.view.ViewCompat
import androidx.core.view.children
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.android.habitica.ui.helpers.bindView
@ -52,6 +55,7 @@ class HabiticaBottomNavigationView @JvmOverloads constructor(
onTabSelectedListener?.invoke(value)
}
private val cutoutBackgroundView: ImageView by bindView(R.id.cutout_background)
private val habitsTab: BottomNavigationItem by bindView(R.id.tab_habits)
private val dailiesTab: BottomNavigationItem by bindView(R.id.tab_dailies)
private val todosTab: BottomNavigationItem by bindView(R.id.tab_todos)
@ -110,6 +114,13 @@ class HabiticaBottomNavigationView @JvmOverloads constructor(
}
submenuWrapper.setOnClickListener { hideSubmenu() }
updateItemSelection()
val cutout = context.getDrawable(R.drawable.bottom_navigation_inset)
cutout?.setColorFilter(context.getThemeColor(R.attr.barColor), PorterDuff.Mode.MULTIPLY)
cutoutBackgroundView.setImageDrawable(cutout)
val fabBackground = context.getDrawable(R.drawable.fab_background)
fabBackground?.setColorFilter(context.getThemeColor(R.attr.colorAccent), PorterDuff.Mode.MULTIPLY)
addButtonBackground.background = fabBackground
}
private fun animateButtonTap() {