This commit is contained in:
coco
2026-07-03 16:23:31 +08:00
commit 7a4fb0e6ae
1979 changed files with 101570 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
minSdk 21
targetSdk 32
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'com.google.android.material:material:1.6.1'
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+174
View File
@@ -0,0 +1,174 @@
> 修改自: https://github.com/garretyoder/Colorful
### Initialization
In your `Application` class, you must initialize Colorful and set the default theme colors.
```kotlin
class SampleApp:Application() {
override fun onCreate() {
super.onCreate()
val defaults:Defaults = Defaults(
primaryColor = ThemeColor.GREEN,
accentColor = ThemeColor.BLUE,
useDarkTheme = false,
translucent = false)
initColorful(this, defaults)
}
}
```
The following is a list of all theme colors available.
```kotlin
ThemeColor.RED
ThemeColor.PINK
ThemeColor.PURPLE
ThemeColor.DEEP_PURPLE
ThemeColor.INDIGO
ThemeColor.BLUE
ThemeColor.LIGHT_BLUE
ThemeColor.CYAN
ThemeColor.TEAL
ThemeColor.GREEN
ThemeColor.LIGHT_GREEN
ThemeColor.LIME
ThemeColor.YELLOW
ThemeColor.AMBER
ThemeColor.ORANGE
ThemeColor.DEEP_ORANGE
ThemeColor.BROWN
ThemeColor.GREY
ThemeColor.BLUE_GREY
ThemeColor.WHITE
ThemeColor.BLACK
```
### Using Themes
Any `Activity` you wish to be automatically themed must inherit from either `CActivity`, `CAppCompatActivity` if you wish to use AppCompat or `CMaterialActivity` if you wish to use the new Material Componets theme. *Note* The material componets theme is still beta and is available only in the testing android-p branch. To use the material-componets theme, please add the android-p colorful branch to your gradle build.
```kotlin
class MainActivity : CActivity()
```
```kotlin
class MainActivity : CAppCompatActivity()
```
*Only available in the android-p branch*
```kotlin
class MainActivity : CMaterialActivity()
```
If you wish to use your own activity, you can manually apply Colorful's theme to any activity using `apply(activity:Activity)`
```kotlin
Colorful().apply(this, override = true, baseTheme = BaseTheme.THEME_MATERIAL)
```
The `override` value will control whether Colorful overrides your activitie's existing base theme, or merely sets primary and accent colors. **Note**: dark/light themeing will not work when override is disabled
The `baseTheme` value will control which base theme Colorful will use, Appcompat, Material, or Material Componets.
Alternatively, as of Colorful 2.1, you can now have your activity inherit from the interface `CThemeInterface` which will provide the `handleOnCreate` and `handleOnResume` methods for automatic theme handling.
See both [CActivity](https://github.com/garretyoder/Colorful/blob/master/library/src/main/java/io/multimoon/colorful/CActivity.kt) and [CAppCompatActivity](https://github.com/garretyoder/Colorful/blob/master/library/src/main/java/io/multimoon/colorful/CAppCompatActivity.kt) for examples on how to implement the `CThemeInterface`
### Setting The Theme
You can set the colors at any time using the `edit()` method
```kotlin
Colorful().edit()
.setPrimaryColor(ThemeColor.RED)
.setAccentColor(ThemeColor.BLUE)
.setDarkTheme(true)
.setTranslucent(true)
.apply(context:Context)
```
You must call `apply(context:Context)` to save your changes
`primaryColor` the primary color of your theme. This affects componets such as toolbars, task descriptions, etc
`accentColor` the accent color of your theme. This affects componets such as buttons, sliders, checkboxes, etc
`darkTheme` the base theme of your style. This controls whether the theme is dark or light.
`translucent` This controls whether translucency is enabled. This will turn the status bar translucent or solid
Colorful will handle saving and loading your theme preferences for you.
The `apply` method optionally takes a high-order function as a argument. This serves as a callback that will be triggered once Colorful has finished it's theme changes. A example usage would be to recreate the current activity after setting a new theme to immediately reflect changes.
```kotlin
Colorful().edit()
.setPrimaryColor(ThemeColor.PURPLE)
.setAccentColor(ThemeColor.GREEN)
.apply(this) {
this.recreate()
}
```
### Getting the current theme values
Colorful can provide you with hex string, or android rgb int formatted values for the currently set colors. This is acheived through the `ColorPack` class, which is a pack that contains both dark and normal variants of the color. These are based off the Material Color Pallet 500 (normal) and 700 (dark) values. Examples are shown below.
```kotlin
Colorful().getPrimaryColor().getColorPack().dark().asInt()
Colorful().getAccentColor().getColorPack().normal().asHex()
```
`Colorful().getDarkTheme()` will return a `boolean` value for whether the dark theme is enabled
`Colorful().getTranslucent()` will return a `boolean` value for whether the current style has transluceny enabled.
### Custom styles
Colorful has beta support for combining your own styles with it's own. This is not yet guaranteed to work reliably.
```kotlin
Colorful().edit()
.setPrimaryColor(ThemeColor.RED)
.setAccentColor(ThemeColor.BLUE)
.setDarkTheme(true)
.setTranslucent(true)
.setCustomThemeOverride(R.style.AppTheme)
.apply(this)
```
The `setCustomThemeOverride` method will allow Colorful to mix a provided theme with it's own. If you wish to set specific theme items yourself, such as coloring all text orange, you can do this within a style file and then have Colorful merge it with it's own theme.
### Custom theme colors
Colorful allows you to define custom themes (e.g. light red primary color with dark yellow accents). If you want to use custom styles you have to do following 3 things:
1. create styles for your custom themes:
```kotlin
<style name="my_custom_primary_color">
<item name="android:colorPrimary">@color/md_red_200</item>
<item name="colorPrimary">@color/md_red_200</item>
</style>
<style name="my_custom_primary_dark_color">
<item name="android:colorPrimaryDark">@color/md_red_400</item>
<item name="colorPrimaryDark">@color/md_red_400</item>
</style>
<style name="my_custom_accent_color">
<item name="android:colorAccent">@color/md_yellow_700</item>
<item name="colorAccent">@color/md_yellow_700</item>
</style>
```
2. Create a custom theme color object, like following:
```kotlin
var myCustomColor1 = CustomThemeColor(
context,
R.style.my_custom_primary_color,
R.style.my_custom_primary_dark_color,
R.color.md_red_200, // <= use the color you defined in my_custom_primary_color
R.color.md_red_400 // <= use the color you defined in my_custom_primary_dark_color
)
// used as accent color, dark color is irrelevant...
var myCustomColor2 = CustomThemeColor(
context,
R.style.my_custom_accent_color,
R.style.my_custom_accent_color,
R.color.md_yellow_700, // <= use the color you defined in my_custom_accent_color
R.color.md_yellow_700 // <= use the color you defined in my_custom_accent_color
)
```
3. use this custom theme color object like you would use any `ThemeColor.<COLOR>` enum object, e.g.
```kotlin
var defaults = Defaults(
primaryColor = myCustomColor1,
accentColor = myCustomColor2,
useDarkTheme = true,
translucent = false,
customTheme = 0
)
```
@@ -0,0 +1 @@
<manifest package="com.ldlywt.colorful"></manifest>
@@ -0,0 +1,26 @@
package com.ldlywt.colorful
import android.app.Application
import android.content.Context
import android.util.Log
var mInstance: ColorfulDelegate? = null
const val darkThemeKey: String = "dark_theme"
const val customThemeKey: String = "custom_theme"
const val translucentKey: String = "translucent"
fun ColorTheme(): ColorfulDelegate {
mInstance?.let { return it }
throw Exception("Colorful has not been initialized! Please call initColorful(app:Application) in your application class before working with Colorful!")
}
fun initColorful(app: Application, colorThemeConfig: ColorThemeConfig) {
val prefs = app.getSharedPreferences(ThemeEditor.PREF_NAME, Context.MODE_PRIVATE)
mInstance = ColorfulDelegate(
ColorThemeConfig(prefs.getBoolean(darkThemeKey, colorThemeConfig.useDarkTheme),
prefs.getBoolean(translucentKey, colorThemeConfig.translucent),
prefs.getInt(customThemeKey, colorThemeConfig.customTheme)))
Log.d("COLORFUL", "defaults: ${colorThemeConfig.customTheme} ---- save: ${prefs.getInt(customThemeKey, colorThemeConfig.customTheme)}")
}
@@ -0,0 +1,14 @@
package com.ldlywt.colorful
import androidx.annotation.StyleRes
/**
* PrimaryColor:主题颜色。app的主要颜色,即整个屏幕和所有控件的主要颜色,首选颜色。
* SecondaryColor:提示性颜色。这颜色一般比PrimaryColor亮一些或暗一些,取决于白天模式还是黑暗模式。一般用于提示相关动作或信息,提示性颜色。
* AccentColor:交互性颜色。这颜色一般用于交互性的控件颜色,比如FloatingButton、TextField、Cursor、ProgressBar、Selection、Links等具体交互性的颜色
*/
data class ColorThemeConfig(
var useDarkTheme: Boolean,
var translucent: Boolean,
@StyleRes var customTheme: Int,
)
@@ -0,0 +1,37 @@
package com.ldlywt.colorful
import android.app.Activity
import android.content.Context
import android.os.Build
import android.view.WindowManager
import androidx.annotation.StyleRes
class ColorfulDelegate(private val config: ColorThemeConfig) {
fun applyTheme(activity: Activity, @StyleRes theme: Int = 0) {
if (theme != 0) {
activity.setTheme(theme)
} else {
activity.setTheme(config.customTheme)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (ColorTheme().getTranslucent()) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
}
fun getDarkTheme(): Boolean = config.useDarkTheme
fun getTranslucent(): Boolean = config.translucent
fun getCustomTheme(): Int = config.customTheme
fun edit(): ThemeEditor {
return ThemeEditor(config)
}
fun clear(context: Context) {
edit().resetPrefs(context)
}
}
@@ -0,0 +1,61 @@
package com.ldlywt.colorful
import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.annotation.StyleRes
import androidx.core.app.ActivityCompat
class ThemeEditor(private val config: ColorThemeConfig) {
companion object {
val PREF_NAME: String = "io.multimoon.colorful.colorvals"
}
fun setDarkTheme(darkTheme: Boolean): ThemeEditor {
this.config.useDarkTheme = darkTheme
return this
}
fun setCustomThemeOverride(@StyleRes customTheme: Int): ThemeEditor {
this.config.customTheme = customTheme
return this
}
fun setTranslucent(translucent: Boolean): ThemeEditor {
this.config.translucent = translucent
return this
}
fun apply(context: Context, callback: () -> Unit = { Log.d("Colorful", "Callback omitted") }) {
applyEdits(context, config)
callback()
}
fun applyAndRestart(activity: Activity) {
applyEdits(activity.applicationContext, config)
if (android.os.Build.VERSION.SDK_INT >= 31) {
// 有的手机会闪屏
ActivityCompat.recreate(activity)
} else {
// 不能在栈底Activity中使用
activity.startActivity(activity.intent)
activity.finish()
activity.overridePendingTransition(0, 0)
}
}
private fun applyEdits(context: Context, config: ColorThemeConfig) {
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
prefs.edit()
.putBoolean(darkThemeKey, config.useDarkTheme)
.putBoolean(translucentKey, config.translucent)
.putInt(customThemeKey, config.customTheme)
.apply()
mInstance = ColorfulDelegate(config)
}
fun resetPrefs(context: Context) {
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit().clear().apply()
}
}
@@ -0,0 +1,11 @@
package com.ldlywt.colorful
import androidx.annotation.StyleRes
enum class ThemeStyle(@StyleRes val res: Int) {
RED(R.style.Theme_Red),
PINK(R.style.Theme_Pink),
ORANGE(R.style.Theme_Orange),
BLUE(R.style.Theme_Blue),
YELLOW(R.style.Theme_Yellow),
}
@@ -0,0 +1,66 @@
<resources>
<style name="Theme.Red" parent="Theme.Base">
<item name="colorPrimary">@color/red_primary_night</item>
<item name="android:colorPrimary">@color/red_primary_night</item>
<item name="colorSecondary">@color/red_second_night</item>
<item name="android:colorSecondary">@color/red_second_night</item>
<item name="colorSurface">@color/red_third_night</item>
</style>
<style name="Theme.Pink" parent="Theme.Base">
<item name="colorPrimary">@color/pink_primary_night</item>
<item name="android:colorPrimary">@color/pink_primary_night</item>
<item name="colorSecondary">@color/pink_second_night</item>
<item name="android:colorSecondary">@color/pink_second_night</item>
<item name="colorSurface">@color/pink_third_night</item>
</style>
<style name="Theme.Orange" parent="Theme.Base">
<item name="colorPrimary">@color/orange_primary_night</item>
<item name="android:colorPrimary">@color/orange_primary_night</item>
<item name="colorSecondary">@color/orange_second_night</item>
<item name="android:colorSecondary">@color/orange_second_night</item>
<item name="colorSurface">@color/orange_third_night</item>
</style>
<style name="Theme.Blue" parent="Theme.Base">
<item name="colorPrimary">@color/blue_primary_night</item>
<item name="android:colorPrimary">@color/blue_primary_night</item>
<item name="colorSecondary">@color/blue_second_night</item>
<item name="android:colorSecondary">@color/blue_second_night</item>
<item name="colorSurface">@color/blue_third_night</item>
</style>
<style name="Theme.Yellow" parent="Theme.Base">
<item name="colorPrimary">@color/yellow_primary_night</item>
<item name="android:colorPrimary">@color/yellow_primary_night</item>
<item name="colorSecondary">@color/yellow_second_night</item>
<item name="android:colorSecondary">@color/yellow_second_night</item>
<item name="colorSurface">@color/yellow_third_night</item>
</style>
<style name="Theme.Edition1" parent="Theme.Base">
<item name="colorPrimary">@color/edition1_primary_night</item>
<item name="android:colorPrimary">@color/edition1_primary_night</item>
<item name="colorSecondary">@color/edition1_second_night</item>
<item name="android:colorSecondary">@color/edition1_second_night</item>
<item name="colorSurface">@color/edition1_third_night</item>
</style>
<!-- Base application theme. -->
<style name="Theme.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimary</item>
<!-- Customize your theme here. -->
<item name="android:colorAccent">?attr/colorPrimary</item>
<item name="colorAccent">?attr/colorPrimary</item>
<item name="android:colorControlActivated">?attr/colorPrimary</item>
<item name="colorControlActivated">?attr/colorPrimary</item>
<item name="translucent70">@color/trans70_night</item>
<item name="translucent50">@color/trans50_night</item>
</style>
</resources>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- background -->
<attr name="eBackground" format="reference"/>
<!-- seekbar -->
<attr name="eSeekBarBackgroundNormal" format="reference" />
<attr name="eSeekBarProgressNormal" format="reference" />
<attr name="eSeekBarBackgroundSmall" format="reference" />
<attr name="eSeekBarProgressSmall" format="reference" />
</resources>
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- red-->
<color name="red_primary">#BF273D</color>
<color name="red_primary_night">#BF273D</color>
<color name="red_second">#8C1D2D</color>
<color name="red_second_night">#8C1D2D</color>
<color name="red_third">#FFF4F7</color>
<color name="red_third_night">#220701</color>
<!-- orange-->
<color name="orange_primary">#FF5D00</color>
<color name="orange_primary_night">#FF5D00</color>
<color name="orange_second">#B32400</color>
<color name="orange_second_night">#B32400</color>
<color name="orange_third">#FFEFE5</color>
<color name="orange_third_night">#372115</color>
<!-- pink-->
<color name="pink_primary">#994D5C</color>
<color name="pink_primary_night">#B35A6B</color>
<color name="pink_second">#80404C</color>
<color name="pink_second_night">#80404C</color>
<color name="pink_third">#FFF4F7</color>
<color name="pink_third_night">#1F0F12</color>
<!-- yellow-->
<color name="yellow_primary">#406380</color>
<color name="yellow_primary_night">#527EA3</color>
<color name="yellow_second">#334F66</color>
<color name="yellow_second_night">#406380</color>
<color name="yellow_third">#F3F5EB</color>
<color name="yellow_third_night">#2B2B2A</color>
<!-- blue-->
<color name="blue_primary">#2152DA</color>
<color name="blue_primary_night">#2152DA</color>
<color name="blue_second">#1B43B3</color>
<color name="blue_second_night">#1B43B3</color>
<color name="blue_third">#E9EFFF</color>
<color name="blue_third_night">#081434</color>
<!-- edition1-->
<color name="edition1_primary">#8E7F6E</color>
<color name="edition1_primary_night">#A69785</color>
<color name="edition1_second">#645A4F</color>
<color name="edition1_second_night">#645A4F</color>
<color name="edition1_third">#FBF5EE</color>
<color name="edition1_third_night">#1A1816</color>
<!-- common-->
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<!-- 叠加此颜色在视觉上实现70透明度 -->
<attr name="translucent70" format="color" />
<color name="trans70">#4DFFFFFF</color>
<color name="trans70_night">#4D000000</color>
<!-- 叠加此颜色在视觉上实现50透明度 -->
<attr name="translucent50" format="color" />
<color name="trans50">#80FFFFFF</color>
<color name="trans50_night">#80000000</color>
</resources>
@@ -0,0 +1,83 @@
<resources>
<!-- Base application theme. -->
<style name="Theme.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimary</item>
<!-- Customize your theme here. -->
<item name="android:colorAccent">?attr/colorPrimary</item>
<item name="colorAccent">?attr/colorPrimary</item>
<item name="android:colorControlActivated">?attr/colorPrimary</item>
<item name="colorControlActivated">?attr/colorPrimary</item>
<item name="translucent70">@color/trans70</item>
<item name="translucent50">@color/trans50</item>
<!-- Widgets style -->
<item name="android:textCursorDrawable">?attr/colorPrimary</item>
<!-- SeekBar background-->
<item name="eSeekBarBackgroundNormal">?attr/colorPrimary</item>
<item name="eSeekBarBackgroundSmall">?attr/colorPrimary</item>
</style>
<style name="Theme.Red" parent="Theme.Base">
<item name="colorPrimary">@color/red_primary</item>
<item name="android:colorPrimary">@color/red_primary</item>
<item name="colorSecondary">@color/red_second</item>
<item name="android:colorSecondary">@color/red_second</item>
<item name="colorSurface">@color/red_third</item>
<item name="eBackground">@color/red_primary</item>
<!-- SeekBar -->
<item name="eSeekBarProgressNormal">@color/red_primary</item>
<item name="eSeekBarProgressSmall">@color/red_primary</item>
</style>
<style name="Theme.Pink" parent="Theme.Base">
<item name="colorPrimary">@color/pink_primary</item>
<item name="android:colorPrimary">@color/pink_primary</item>
<item name="colorSecondary">@color/pink_second</item>
<item name="android:colorSecondary">@color/pink_second</item>
<item name="colorSurface">@color/pink_third</item>
<item name="eBackground">@color/pink_primary</item>
<!-- SeekBar -->
<item name="eSeekBarProgressNormal">@color/pink_primary</item>
<item name="eSeekBarProgressSmall">@color/pink_primary</item>
</style>
<style name="Theme.Orange" parent="Theme.Base">
<item name="colorPrimary">@color/orange_primary</item>
<item name="android:colorPrimary">@color/orange_primary</item>
<item name="colorSecondary">@color/orange_second</item>
<item name="android:colorSecondary">@color/orange_second</item>
<item name="colorSurface">@color/orange_third</item>
<item name="eBackground">@color/orange_primary</item>
<!-- SeekBar -->
<item name="eSeekBarProgressNormal">@color/orange_primary</item>
<item name="eSeekBarProgressSmall">@color/orange_primary</item>
</style>
<style name="Theme.Blue" parent="Theme.Base">
<item name="colorPrimary">@color/blue_primary</item>
<item name="android:colorPrimary">@color/blue_primary</item>
<item name="colorSecondary">@color/blue_second</item>
<item name="android:colorSecondary">@color/blue_second</item>
<item name="colorSurface">@color/blue_third</item>
<item name="eBackground">@color/blue_primary</item>
<!-- SeekBar -->
<item name="eSeekBarProgressNormal">@color/blue_primary</item>
<item name="eSeekBarProgressSmall">@color/blue_primary</item>
</style>
<style name="Theme.Yellow" parent="Theme.Base">
<item name="colorPrimary">@color/yellow_primary</item>
<item name="android:colorPrimary">@color/yellow_primary</item>
<item name="colorSecondary">@color/yellow_second</item>
<item name="android:colorSecondary">@color/yellow_second</item>
<item name="colorSurface">@color/yellow_third</item>
<item name="eBackground">@color/yellow_primary</item>
<!-- SeekBar -->
<item name="eSeekBarProgressNormal">@color/yellow_primary</item>
<item name="eSeekBarProgressSmall">@color/yellow_primary</item>
</style>
</resources>