├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── Bug_report.md
│ └── Feature_request.md
└── pull_request_template.md
├── .gitignore
├── .travis.yml
├── LICENSE.md
├── README.md
├── bintrayconfig.gradle
├── build.gradle
├── dependencies.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
└── 6.jpg
├── library
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── afollestad
│ │ └── aesthetic
│ │ ├── Aesthetic.kt
│ │ ├── AestheticActivity.kt
│ │ ├── Modes.kt
│ │ ├── States.kt
│ │ ├── internal
│ │ ├── AestheticExt.kt
│ │ ├── AttrWizard.kt
│ │ ├── InflationDelegate.kt
│ │ ├── InflationInterceptor.kt
│ │ └── PrefNames.kt
│ │ ├── utils
│ │ ├── ActivityExt.kt
│ │ ├── AttrObservableExt.kt
│ │ ├── ClassExt.kt
│ │ ├── CollectionExt.kt
│ │ ├── ColorExt.kt
│ │ ├── ContextExt.kt
│ │ ├── EdgeGlowUtil.kt
│ │ ├── PackageManagerExt.kt
│ │ ├── PrefsExt.kt
│ │ ├── ResourcesExt.kt
│ │ ├── RxExt.kt
│ │ ├── StringExt.kt
│ │ ├── TintHelper.kt
│ │ └── ViewExt.kt
│ │ └── views
│ │ ├── AestheticActionMenuItemView.kt
│ │ ├── AestheticBorderlessButton.kt
│ │ ├── AestheticBottomAppBar.kt
│ │ ├── AestheticBottomNavigationView.kt
│ │ ├── AestheticButton.kt
│ │ ├── AestheticCardView.kt
│ │ ├── AestheticCheckBox.kt
│ │ ├── AestheticCheckedTextView.kt
│ │ ├── AestheticCoordinatorLayout.kt
│ │ ├── AestheticDialogButton.kt
│ │ ├── AestheticDrawerLayout.kt
│ │ ├── AestheticEditText.kt
│ │ ├── AestheticFab.kt
│ │ ├── AestheticListView.kt
│ │ ├── AestheticNavigationView.kt
│ │ ├── AestheticNestedScrollView.kt
│ │ ├── AestheticProgressBar.kt
│ │ ├── AestheticRadioButton.kt
│ │ ├── AestheticRatingBar.kt
│ │ ├── AestheticRecyclerView.kt
│ │ ├── AestheticScrollView.kt
│ │ ├── AestheticSeekBar.kt
│ │ ├── AestheticSnackBarContentLayout.kt
│ │ ├── AestheticSpinner.kt
│ │ ├── AestheticSwipeRefreshLayout.kt
│ │ ├── AestheticSwitch.kt
│ │ ├── AestheticSwitchCompat.kt
│ │ ├── AestheticTabLayout.kt
│ │ ├── AestheticTextInputEditText.kt
│ │ ├── AestheticTextInputLayout.kt
│ │ ├── AestheticToolbar.kt
│ │ └── AestheticViewPager.kt
│ ├── res-public
│ └── values
│ │ └── public.xml
│ └── res
│ └── values
│ ├── colors.xml
│ └── ids.xml
├── sample-appcompat
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── afollestad
│ │ └── aestheticsample
│ │ └── appcompat
│ │ ├── AppCompatDemoActivity.kt
│ │ ├── DrawerActivity.kt
│ │ ├── MainAdapter.kt
│ │ ├── MainFragment.kt
│ │ ├── MainPagerAdapter.kt
│ │ ├── RecyclerViewActivity.kt
│ │ ├── SecondaryFragment.kt
│ │ ├── SettingsActivity.kt
│ │ └── SwipeRefreshActivity.kt
│ └── res
│ ├── drawable
│ ├── ic_announcement.xml
│ ├── ic_archive.xml
│ ├── ic_arrow_back.xml
│ ├── ic_attach_money.xml
│ ├── ic_backup.xml
│ ├── ic_book.xml
│ ├── ic_check.xml
│ ├── ic_close.xml
│ ├── ic_info.xml
│ ├── ic_search.xml
│ └── ic_watch.xml
│ ├── layout
│ ├── activity_demo_appcompat.xml
│ ├── activity_drawer.xml
│ ├── activity_recyclerview.xml
│ ├── activity_settings.xml
│ ├── activity_swipe_refresh.xml
│ ├── drawer_header.xml
│ ├── fragment_main.xml
│ ├── fragment_secondary.xml
│ ├── list_item_rv.xml
│ ├── list_item_spinner.xml
│ └── list_item_spinner_dropdown.xml
│ ├── menu
│ ├── bottomtabs.xml
│ ├── coordinatorlayout.xml
│ ├── drawer.xml
│ └── main.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── values
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── preferences.xml
├── sample-materialcomponents
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── afollestad
│ │ └── aestheticsample
│ │ └── materialcomponents
│ │ └── MaterialComponentsDemoActivity.kt
│ └── res
│ ├── drawable
│ ├── ic_3d_rotation_24px.xml
│ ├── ic_accelerator_24px.xml
│ ├── ic_add_24px.xml
│ ├── ic_dashboard_24px.xml
│ ├── ic_drawer_menu_24px.xml
│ └── ic_search_24px.xml
│ ├── layout
│ ├── activity_demo_materialcomponents.xml
│ └── main_content.xml
│ ├── menu
│ └── demo_primary.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── sample.apk
├── settings.gradle
├── spotless.gradle
├── spotless.license.kt
└── versionsPlugin.gradle
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.kt]
2 | indent_size = 2
3 | continuation_indent_size=4
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Something is crashing or not working as intended
4 | labels: bug
5 |
6 | ---
7 |
8 | *Please consider making a Pull Request if you are capable of doing so.*
9 |
10 | **Library Version:**
11 |
12 | 1.x.x
13 |
14 | **Affected Device(s):**
15 |
16 | Google Pixel 3 XL with Android 9.0
17 |
18 | **Describe the Bug:**
19 |
20 | A clear description of what is the bug is.
21 |
22 | **To Reproduce:**
23 | 1.
24 | 2.
25 | 3.
26 |
27 | **Expected Behavior:**
28 |
29 | A clear description of what you expected to happen.
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | labels: enhancement
5 |
6 | ---
7 |
8 | *Please consider making a Pull Request if you are capable of doing so.*
9 |
10 | **What module does this apply to?**
11 |
12 | Core? Input? Files? Color?
13 |
14 | **Description what you'd like to happen:**
15 |
16 | A clear description if the feature or behavior you'd like implemented.
17 |
18 | **Describe alternatives you've considered:**
19 |
20 | A clear description of any alternative solutions you've considered.
21 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ### Guidelines
2 |
3 | 1. You must run the `spotlessApply` task before commiting, either through Android Studio or with `./gradlew spotlessApply`.
4 | 2. A PR should be focused and contained. If you are changing multiple unrelated things, they should be in separate PRs.
5 | 3. A PR should fix a bug or solve a problem - something that only you would use is not necessarily something that should be published.
6 | 4. Give your PR a detailed title and description - look over your code one last time before actually creating the PR. Give it a self-review.
7 |
8 | **If you do not follow the guidelines, your PR will be rejected.**
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/osx,macos,android,windows,androidstudio
3 |
4 | ### Android ###
5 | # Built application files
6 | *.ap_
7 |
8 | # Files for the ART/Dalvik VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # Generated files
15 | bin/
16 | gen/
17 | out/
18 |
19 | # Gradle files
20 | .gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 |
32 | # Android Studio Navigation editor temp files
33 | .navigation/
34 |
35 | # Android Studio captures folder
36 | captures/
37 |
38 | # Intellij
39 | *.iml
40 | .idea/workspace.xml
41 | .idea/tasks.xml
42 | .idea/gradle.xml
43 | .idea/dictionaries
44 | .idea/libraries
45 |
46 | # Keystore files
47 | *.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | ### Android Patch ###
61 | gen-external-apklibs
62 |
63 | ### AndroidStudio ###
64 | # Covers files to be ignored for android development using Android Studio.
65 |
66 | # Built application files
67 |
68 | # Files for the ART/Dalvik VM
69 |
70 | # Java class files
71 |
72 | # Generated files
73 |
74 | # Gradle files
75 | .gradle
76 |
77 | # Signing files
78 | .signing/
79 |
80 | # Local configuration file (sdk path, etc)
81 |
82 | # Proguard folder generated by Eclipse
83 |
84 | # Log Files
85 |
86 | # Android Studio
87 | /*/build/
88 | /*/local.properties
89 | /*/out
90 | /*/*/build
91 | /*/*/production
92 | *.ipr
93 | *~
94 | *.swp
95 |
96 | # Android Patch
97 |
98 | # External native build folder generated in Android Studio 2.2 and later
99 |
100 | # NDK
101 | obj/
102 |
103 | # IntelliJ IDEA
104 | *.iws
105 | /out/
106 |
107 | # User-specific configurations
108 | .idea/libraries/
109 | .idea/.name
110 | .idea/compiler.xml
111 | .idea/copyright/profiles_settings.xml
112 | .idea/encodings.xml
113 | .idea/misc.xml
114 | .idea/modules.xml
115 | .idea/scopes/scope_settings.xml
116 | .idea/vcs.xml
117 | .idea/jsLibraryMappings.xml
118 | .idea/datasources.xml
119 | .idea/dataSources.ids
120 | .idea/sqlDataSources.xml
121 | .idea/dynamic.xml
122 | .idea/uiDesigner.xml
123 |
124 | # Keystore files
125 |
126 | # OS-specific files
127 | .DS_Store
128 | .DS_Store?
129 | ._*
130 | .Spotlight-V100
131 | .Trashes
132 | ehthumbs.db
133 | Thumbs.db
134 |
135 | # Legacy Eclipse project files
136 | .classpath
137 | .project
138 |
139 | # Mobile Tools for Java (J2ME)
140 | .mtj.tmp/
141 |
142 | # Package Files #
143 | *.jar
144 | *.war
145 | *.ear
146 |
147 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
148 | hs_err_pid*
149 |
150 | ## Plugin-specific files:
151 |
152 | # mpeltonen/sbt-idea plugin
153 | .idea_modules/
154 |
155 | # JIRA plugin
156 | atlassian-ide-plugin.xml
157 |
158 | # Mongo Explorer plugin
159 | .idea/mongoSettings.xml
160 |
161 | # Crashlytics plugin (for Android Studio and IntelliJ)
162 | com_crashlytics_export_strings.xml
163 | crashlytics.properties
164 | crashlytics-build.properties
165 | fabric.properties
166 |
167 | ### AndroidStudio Patch ###
168 | # Google Services plugin
169 |
170 | !/gradle/wrapper/gradle-wrapper.jar
171 |
172 | ### macOS ###
173 | *.DS_Store
174 | .AppleDouble
175 | .LSOverride
176 |
177 | # Icon must end with two \r
178 | Icon
179 |
180 | # Thumbnails
181 |
182 | # Files that might appear in the root of a volume
183 | .DocumentRevisions-V100
184 | .fseventsd
185 | .TemporaryItems
186 | .VolumeIcon.icns
187 | .com.apple.timemachine.donotpresent
188 |
189 | # Directories potentially created on remote AFP share
190 | .AppleDB
191 | .AppleDesktop
192 | Network Trash Folder
193 | Temporary Items
194 | .apdisk
195 |
196 | ### OSX ###
197 |
198 | # Icon must end with two \r
199 |
200 | # Thumbnails
201 |
202 | # Files that might appear in the root of a volume
203 |
204 | # Directories potentially created on remote AFP share
205 |
206 | ### Windows ###
207 | # Windows thumbnail cache files
208 | ehthumbs_vista.db
209 |
210 | # Folder config file
211 | Desktop.ini
212 |
213 | # Recycle Bin used on file shares
214 | $RECYCLE.BIN/
215 |
216 | # Windows Installer files
217 | *.cab
218 | *.msi
219 | *.msm
220 | *.msp
221 |
222 | # Windows shortcuts
223 | *.lnk
224 |
225 | # End of https://www.gitignore.io/api/osx,macos,android,windows,androidstudio
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | dist: trusty
3 | android:
4 | components:
5 | - tools
6 | - platform-tools
7 | - build-tools-29.0.0
8 | - android-29
9 | - extra-android-support
10 | - extra-android-m2repository
11 | - extra-google-m2repository
12 |
13 | licenses:
14 | - '.+'
15 |
--------------------------------------------------------------------------------
/bintrayconfig.gradle:
--------------------------------------------------------------------------------
1 | if (!project.rootProject.file('local.properties').exists()) {
2 | println "Not applying bintrayconfig.gradle"
3 | return
4 | }
5 | apply plugin: 'com.novoda.bintray-release'
6 |
7 | def getBintrayUserAndKey() {
8 | Properties properties = new Properties()
9 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
10 | return [
11 | properties.getProperty("bintray.user"),
12 | properties.getProperty("bintray.apikey")
13 | ]
14 | }
15 |
16 | if (versions == null || versions.publishVersion == null) {
17 | throw new IllegalStateException("Unable to reference publishVersion")
18 | }
19 |
20 | task checkBintrayConfig {
21 | doLast {
22 | def (user, key) = getBintrayUserAndKey()
23 | if (user == null || user.isEmpty() ||
24 | key == null || key.isEmpty()) {
25 | throw new IllegalStateException("Must specify Bintray user/API key in your local.properties.")
26 | }
27 | }
28 | }
29 |
30 | afterEvaluate {
31 | bintrayUpload.dependsOn checkBintrayConfig
32 | }
33 |
34 | def (user, key) = getBintrayUserAndKey()
35 | publish {
36 | bintrayUser = user
37 | bintrayKey = key
38 | userOrg = 'drummer-aidan'
39 | groupId = 'com.afollestad'
40 | artifactId = 'aesthetic'
41 | publishVersion = versions.publishVersion
42 | desc =
43 | '[BETA] A fast and easy to use plug-and-play dynamic theme engine. Powered by Rx, for Android apps.'
44 | website = 'https://github.com/afollestad/aesthetic'
45 | dryRun = false
46 | override = true
47 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: './dependencies.gradle'
2 | apply from: './versionsPlugin.gradle'
3 |
4 | buildscript {
5 | apply from: './dependencies.gradle'
6 |
7 | repositories {
8 | google()
9 | jcenter()
10 | }
11 |
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:' + versions.gradlePlugin
14 | classpath "com.diffplug.spotless:spotless-plugin-gradle:" + versions.spotlessPlugin
15 | classpath 'com.novoda:bintray-release:' + versions.bintrayRelease
16 | classpath 'com.github.ben-manes:gradle-versions-plugin:' + versions.versionsPlugin
17 | classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:' + versions.kotlin
18 | }
19 | }
20 |
21 | allprojects {
22 | repositories {
23 | google()
24 | jcenter()
25 | }
26 |
27 | tasks.withType(Javadoc).all {
28 | enabled = false
29 | }
30 | }
--------------------------------------------------------------------------------
/dependencies.gradle:
--------------------------------------------------------------------------------
1 | ext.versions = [
2 | minSdk : 16,
3 | compileSdk : 29,
4 | buildTools : '29.0.0',
5 | publishVersion : '1.0.0-beta05',
6 | publishVersionCode: 33,
7 |
8 | gradlePlugin : '3.4.1',
9 | kotlin : '1.3.31',
10 | spotlessPlugin : '3.22.0',
11 | versionsPlugin : '0.20.0',
12 | bintrayRelease : '0.9.1',
13 |
14 | androidxCore : '1.0.2',
15 | androidx : '1.0.0',
16 |
17 | rxJava : '2.2.6',
18 | rxAndroid : '2.1.1',
19 | rxkPrefs : '1.2.5',
20 | leakCanary : '1.6.1'
21 | ]
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 | org.gradle.configureondemand=false
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useAndroidX=true
21 | android.enableJetifier=true
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jul 17 12:42:56 PDT 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/images/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/1.jpg
--------------------------------------------------------------------------------
/images/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/2.jpg
--------------------------------------------------------------------------------
/images/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/3.jpg
--------------------------------------------------------------------------------
/images/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/4.jpg
--------------------------------------------------------------------------------
/images/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/5.jpg
--------------------------------------------------------------------------------
/images/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/images/6.jpg
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: '../dependencies.gradle'
2 | apply plugin: 'com.android.library'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | apply from: '../bintrayconfig.gradle'
7 |
8 | android {
9 | compileSdkVersion versions.compileSdk
10 | buildToolsVersion versions.buildTools
11 |
12 | defaultConfig {
13 | minSdkVersion versions.minSdk
14 | targetSdkVersion versions.compileSdk
15 | versionCode versions.publishVersionCode
16 | versionName versions.publishVersion
17 | }
18 |
19 | sourceSets {
20 | main.res.srcDirs = [
21 | 'src/main/res',
22 | 'src/main/res-public'
23 | ]
24 | }
25 |
26 | compileOptions {
27 | kotlinOptions.freeCompilerArgs += ['-module-name', "com.afollestad.aesthetic"]
28 | }
29 |
30 | packagingOptions {
31 | pickFirst 'META-INF/proguard/androidx-annotations.pro'
32 | }
33 | }
34 |
35 | repositories {
36 | google()
37 | jcenter()
38 | }
39 |
40 | dependencies {
41 | api 'androidx.appcompat:appcompat:' + versions.androidxCore
42 |
43 | implementation 'androidx.cardview:cardview:' + versions.androidx
44 | implementation 'androidx.recyclerview:recyclerview:' + versions.androidx
45 | implementation 'com.google.android.material:material:' + versions.androidx
46 |
47 | implementation 'io.reactivex.rxjava2:rxjava:' + versions.rxJava
48 | implementation 'io.reactivex.rxjava2:rxandroid:' + versions.rxAndroid
49 | implementation 'com.afollestad:rxkprefs:' + versions.rxkPrefs
50 |
51 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:' + versions.kotlin
52 | }
53 |
54 | apply from: '../spotless.gradle'
55 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/AestheticActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic
17 |
18 | import android.os.Bundle
19 | import androidx.appcompat.app.AppCompatActivity
20 | import com.afollestad.aesthetic.internal.InflationDelegate
21 |
22 | /** @author Aidan Follestad (afollestad) */
23 | open class AestheticActivity : AppCompatActivity() {
24 |
25 | open fun getInflationDelegate(): InflationDelegate? = null
26 |
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | Aesthetic.attach(this, getInflationDelegate())
29 | super.onCreate(savedInstanceState)
30 | }
31 |
32 | override fun onResume() {
33 | super.onResume()
34 | Aesthetic.resume(this)
35 | }
36 |
37 | override fun onPause() {
38 | Aesthetic.pause(this)
39 | super.onPause()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/Modes.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | @file:Suppress("unused")
17 |
18 | package com.afollestad.aesthetic
19 |
20 | import io.reactivex.Observable
21 |
22 | @Deprecated(message = "Use ColorMode instead.", replaceWith = ReplaceWith("ColorMode"))
23 | typealias TabLayoutBgMode = ColorMode
24 |
25 | @Deprecated(message = "Use ColorMode instead.", replaceWith = ReplaceWith("ColorMode"))
26 | typealias TabLayoutIndicatorMode = ColorMode
27 |
28 | /** @author Aidan Follestad (afollestad)*/
29 | enum class ColorMode(val value: Int) {
30 | PRIMARY(0),
31 | ACCENT(1);
32 |
33 | companion object {
34 | internal fun fromInt(value: Int): ColorMode {
35 | return when (value) {
36 | 0 -> PRIMARY
37 | else -> ACCENT
38 | }
39 | }
40 | }
41 | }
42 |
43 | internal fun Observable.mapToColorMode(): Observable {
44 | return map { ColorMode.fromInt(it) }
45 | }
46 |
47 | /** @author Aidan Follestad (afollestad) */
48 | enum class NavigationViewMode(val value: Int) {
49 | SELECTED_PRIMARY(0),
50 | SELECTED_ACCENT(1),
51 | NONE(2);
52 |
53 | companion object {
54 | internal fun fromInt(value: Int): NavigationViewMode {
55 | return when (value) {
56 | 0 -> SELECTED_PRIMARY
57 | 1 -> SELECTED_ACCENT
58 | else -> NONE
59 | }
60 | }
61 | }
62 | }
63 |
64 | internal fun Observable.mapToNavigationViewMode(): Observable {
65 | return map { NavigationViewMode.fromInt(it) }
66 | }
67 |
68 | /** @author Aidan Follestad (afollestad) */
69 | enum class AutoSwitchMode(val value: Int) {
70 | OFF(0),
71 | ON(1),
72 | AUTO(2);
73 |
74 | companion object {
75 | internal fun fromInt(value: Int): AutoSwitchMode {
76 | return when (value) {
77 | 0 -> OFF
78 | 1 -> ON
79 | else -> AUTO
80 | }
81 | }
82 | }
83 | }
84 |
85 | internal fun Observable.mapToAutoSwitchMode(): Observable {
86 | return map { AutoSwitchMode.fromInt(it) }
87 | }
88 |
89 | /** @author Aidan Follestad (afollestad) */
90 | enum class BottomNavBgMode(val value: Int) {
91 | BLACK_WHITE_AUTO(0),
92 | PRIMARY(1),
93 | PRIMARY_DARK(2),
94 | ACCENT(3),
95 | NONE(4);
96 |
97 | companion object {
98 | internal fun fromInt(value: Int): BottomNavBgMode {
99 | return when (value) {
100 | 0 -> BLACK_WHITE_AUTO
101 | 1 -> PRIMARY
102 | 2 -> PRIMARY_DARK
103 | 3 -> ACCENT
104 | else -> NONE
105 | }
106 | }
107 | }
108 | }
109 |
110 | internal fun Observable.mapToBottomNavBgMode(): Observable {
111 | return map { BottomNavBgMode.fromInt(it) }
112 | }
113 |
114 | /** @author Aidan Follestad (afollestad) */
115 | enum class BottomNavIconTextMode(val value: Int) {
116 | SELECTED_PRIMARY(0),
117 | SELECTED_ACCENT(1),
118 | BLACK_WHITE_AUTO(2),
119 | NONE(3);
120 |
121 | companion object {
122 | internal fun fromInt(value: Int): BottomNavIconTextMode {
123 | return when (value) {
124 | 0 -> SELECTED_PRIMARY
125 | 1 -> SELECTED_ACCENT
126 | 2 -> BLACK_WHITE_AUTO
127 | else -> NONE
128 | }
129 | }
130 | }
131 | }
132 |
133 | internal fun Observable.mapToBottomNavIconTextMode(): Observable {
134 | return map { BottomNavIconTextMode.fromInt(it) }
135 | }
136 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/States.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic
17 |
18 | import android.R.attr
19 | import android.content.res.ColorStateList
20 | import androidx.annotation.ColorInt
21 |
22 | /** @author Aidan Follestad (afollestad) */
23 | internal data class ActiveInactiveColors(
24 | @field:ColorInt val activeColor: Int,
25 | @field:ColorInt val inactiveColor: Int
26 | ) {
27 | fun toEnabledSl(): ColorStateList {
28 | return ColorStateList(
29 | arrayOf(
30 | intArrayOf(attr.state_enabled), intArrayOf(-attr.state_enabled)
31 | ),
32 | intArrayOf(activeColor, inactiveColor)
33 | )
34 | }
35 | }
36 |
37 | /** @author Aidan Follestad (afollestad) */
38 | internal data class ColorIsDarkState(
39 | @field:ColorInt val color: Int,
40 | val isDark: Boolean
41 | )
42 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/internal/AttrWizard.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.internal
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.annotation.AttrRes
21 | import com.afollestad.aesthetic.utils.isNumber
22 | import com.afollestad.aesthetic.utils.safeResourceName
23 |
24 | /** @author Aidan Follestad (afollestad) */
25 | internal class AttrWizard(
26 | private val context: Context,
27 | private val attrs: AttributeSet?
28 | ) {
29 |
30 | fun getRawValue(@AttrRes attrId: Int): String {
31 | if (attrs == null || attrId == 0) {
32 | return ""
33 | }
34 |
35 | val res = context.resources
36 | val attrName = res.safeResourceName(attrId)
37 | val attrIndex = attrs.indexOfAttr(context) { it == attrName }
38 | if (attrIndex == -1) {
39 | return ""
40 | }
41 |
42 | val attrValue = attrs.getAttributeValue(attrIndex)
43 | return when {
44 | attrValue.startsWith('@') || attrValue.startsWith('?') -> {
45 | val rawId = attrValue.substring(1)
46 | var resName = if (rawId.isNumber()) {
47 | val id = rawId.toInt()
48 | if (id == 0) {
49 | return ""
50 | }
51 | res.safeResourceName(id)
52 | } else {
53 | rawId
54 | }
55 | if (!resName.startsWith("android")) {
56 | resName = resName.substring(resName.indexOf(':') + 1)
57 | }
58 | "${attrValue[0]}$resName"
59 | }
60 | else -> attrValue
61 | }
62 | }
63 | }
64 |
65 | private fun AttributeSet.indexOfAttr(
66 | context: Context,
67 | matcher: (String) -> (Boolean)
68 | ): Int {
69 | for (i in 0 until attributeCount) {
70 | val nameResource = getAttributeNameResource(i)
71 | val literalName = context.resources.safeResourceName(nameResource)
72 | if (matcher(literalName)) {
73 | return i
74 | }
75 | }
76 | return -1
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/internal/InflationDelegate.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.internal
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import android.view.View
21 | import androidx.annotation.IdRes
22 |
23 | /** @author Aidan Follestad (afollestad) */
24 | interface InflationDelegate {
25 |
26 | fun createView(
27 | context: Context,
28 | attrs: AttributeSet?,
29 | name: String,
30 | @IdRes viewId: Int
31 | ): View?
32 | }
33 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/internal/PrefNames.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.internal
17 |
18 | // Base
19 | const val PREFS_NAME = "[aesthetic-prefs]"
20 | const val KEY_FIRST_TIME = "first_time"
21 | const val KEY_ACTIVITY_THEME = "activity_theme_default"
22 | const val KEY_IS_DARK = "is_dark"
23 | const val KEY_ATTRIBUTE = "ate_attribute.%s"
24 |
25 | // Legacy Attributes
26 | @Deprecated("Legacy attribute")
27 | const val KEY_PRIMARY_COLOR = "primary_color"
28 | @Deprecated("Legacy attribute")
29 | const val KEY_PRIMARY_DARK_COLOR = "primary_dark_color"
30 | @Deprecated("Legacy attribute")
31 | const val KEY_ACCENT_COLOR = "accent_color"
32 | @Deprecated("Legacy attribute")
33 | const val KEY_PRIMARY_TEXT_COLOR = "primary_text"
34 | @Deprecated("Legacy attribute")
35 | const val KEY_SECONDARY_TEXT_COLOR = "secondary_text"
36 | @Deprecated("Legacy attribute")
37 | const val KEY_PRIMARY_TEXT_INVERSE_COLOR = "primary_text_inverse"
38 | @Deprecated("Legacy attribute")
39 | const val KEY_SECONDARY_TEXT_INVERSE_COLOR = "secondary_text_inverse"
40 | @Deprecated("Legacy attribute")
41 | const val KEY_WINDOW_BG_COLOR = "window_bg_color"
42 | @Deprecated("Legacy attribute")
43 | const val KEY_ICON_TITLE_ACTIVE_COLOR = "icon_title_active_color"
44 | @Deprecated("Legacy attribute")
45 | const val KEY_ICON_TITLE_INACTIVE_COLOR = "icon_title_inactive_color"
46 |
47 | // Window/System
48 | const val KEY_STATUS_BAR_COLOR = "status_bar_color_default"
49 | const val KEY_NAV_BAR_COLOR = "nav_bar_color_default"
50 | const val KEY_LIGHT_STATUS_MODE = "light_status_mode"
51 | const val KEY_LIGHT_NAV_MODE = "light_navigation_bar_mode"
52 |
53 | // Custom Views
54 | const val KEY_TOOLBAR_ICON_COLOR = "toolbar_icon_color"
55 | const val KEY_TOOLBAR_TITLE_COLOR = "toolbar_title_color"
56 | const val KEY_TOOLBAR_SUBTITLE_COLOR = "toolbar_subtitle_color"
57 | const val KEY_TAB_LAYOUT_BG_MODE = "tab_layout_bg_mode"
58 | const val KEY_TAB_LAYOUT_INDICATOR_MODE = "tab_layout_indicator_mode"
59 | const val KEY_NAV_VIEW_MODE = "nav_view_mode"
60 | const val KEY_BOTTOM_NAV_BG_MODE = "bottom_nav_bg_mode"
61 | const val KEY_BOTTOM_NAV_ICONTEXT_MODE = "bottom_nav_icontext_mode"
62 | const val KEY_CARD_VIEW_BG_COLOR = "card_view_bg_color"
63 | const val KEY_SNACKBAR_TEXT = "snackbar_text_color"
64 | const val KEY_SNACKBAR_ACTION_TEXT = "snackbar_action_text_color"
65 | const val KEY_SNACKBAR_BG_COLOR = "snackbar_bg_color"
66 | const val KEY_SWIPEREFRESH_COLORS = "swiperefreshlayout_colors"
67 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/ActivityExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.annotation.TargetApi
19 | import android.app.Activity
20 | import android.app.ActivityManager
21 | import android.graphics.Bitmap
22 | import android.graphics.drawable.BitmapDrawable
23 | import android.os.Build
24 | import android.os.Build.VERSION.SDK_INT
25 | import android.os.Build.VERSION_CODES.LOLLIPOP
26 | import android.os.Build.VERSION_CODES.M
27 | import android.os.Build.VERSION_CODES.O
28 | import android.view.LayoutInflater
29 | import android.view.View
30 | import android.view.ViewGroup
31 | import androidx.annotation.ColorInt
32 | import androidx.appcompat.app.AppCompatActivity
33 | import androidx.core.view.LayoutInflaterCompat.setFactory2
34 | import com.afollestad.aesthetic.internal.InflationDelegate
35 | import com.afollestad.aesthetic.internal.InflationInterceptor
36 |
37 | internal fun AppCompatActivity.setInflaterFactory(
38 | li: LayoutInflater,
39 | aestheticDelegate: InflationDelegate?
40 | ) = setFactory2(li, InflationInterceptor(this, aestheticDelegate, delegate))
41 |
42 | internal fun Activity.setStatusBarColorCompat(@ColorInt color: Int) {
43 | if (SDK_INT >= LOLLIPOP) {
44 | window.statusBarColor = color
45 | }
46 | }
47 |
48 | internal fun Activity.getRootView(): ViewGroup? {
49 | val content = findViewById(android.R.id.content)
50 | if (content != null && content.getChildAt(0) is ViewGroup) {
51 | return content.getChildAt(0) as ViewGroup
52 | }
53 | return null
54 | }
55 |
56 | internal fun Activity?.setNavBarColorCompat(@ColorInt color: Int) {
57 | if (SDK_INT >= LOLLIPOP) {
58 | this?.window?.navigationBarColor = color
59 | }
60 | }
61 |
62 | internal fun Activity?.setLightStatusBarCompat(lightMode: Boolean) {
63 | val view = this?.window?.decorView ?: return
64 | if (SDK_INT >= M) {
65 | var flags = view.systemUiVisibility
66 | flags = if (lightMode) {
67 | flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
68 | } else {
69 | flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
70 | }
71 | view.systemUiVisibility = flags
72 | }
73 | }
74 |
75 | internal fun Activity?.setLightNavBarCompat(lightMode: Boolean) {
76 | val view = this?.window?.decorView ?: return
77 | if (SDK_INT >= O) {
78 | var flags = view.systemUiVisibility
79 | flags = if (lightMode) {
80 | flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
81 | } else {
82 | flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
83 | }
84 | view.systemUiVisibility = flags
85 | }
86 | }
87 |
88 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
89 | internal fun Activity?.setTaskDescriptionColor(@ColorInt requestedColor: Int) {
90 | if (this == null || SDK_INT <= LOLLIPOP) return
91 | var color = requestedColor
92 |
93 | // Task description requires fully opaque color
94 | color = color.stripAlpha()
95 | // Default is app's launcher icon
96 | val icon: Bitmap? = if (Build.VERSION.SDK_INT >= 26) {
97 | packageManager.getAppIcon(packageName)
98 | } else {
99 | (applicationInfo.loadIcon(packageManager) as BitmapDrawable)
100 | .bitmap
101 | }
102 | if (icon != null) {
103 | // Sets color of entry in the system recents page
104 | @Suppress("DEPRECATION")
105 | val td = ActivityManager.TaskDescription(title as String, icon, color)
106 | setTaskDescription(td)
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/AttrObservableExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import androidx.annotation.CheckResult
19 | import com.afollestad.aesthetic.Aesthetic
20 | import io.reactivex.Observable
21 | import io.reactivex.Observable.empty
22 |
23 | @CheckResult internal fun Aesthetic.observableForAttrName(
24 | name: String,
25 | fallback: Observable? = null
26 | ): Observable? {
27 | if (name.isNotEmpty() && !name.startsWith('?')) {
28 | // Don't override the hardcoded or resource value that is set.
29 | return empty()
30 | }
31 | return when (name) {
32 | "" -> fallback
33 |
34 | "?attr/colorPrimary", "?android:attr/colorPrimary" -> colorPrimary()
35 | "?attr/colorPrimaryDark", "?android:attr/colorPrimaryDark" -> colorPrimaryDark()
36 | "?attr/colorAccent", "?android:attr/colorAccent" -> colorAccent()
37 |
38 | "?android:attr/statusBarColor" -> colorStatusBar()
39 | "?android:attr/navigationBarColor" -> colorNavigationBar()
40 | "?android:attr/windowBackground" -> colorWindowBackground()
41 |
42 | "?android:attr/textColorPrimary" -> textColorPrimary()
43 | "?android:attr/textColorPrimaryInverse" -> textColorPrimaryInverse()
44 | "?android:attr/textColorSecondary" -> textColorSecondary()
45 | "?android:attr/textColorSecondaryInverse" -> textColorSecondaryInverse()
46 |
47 | else -> fallback ?: attribute(name.substring(1))
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/ClassExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import java.lang.reflect.Field
19 | import kotlin.reflect.KClass
20 |
21 | internal fun KClass.findField(vararg nameOptions: String): Field = with(java) {
22 | for (name in nameOptions) {
23 | try {
24 | val field = getDeclaredField(name)
25 | field.isAccessible = true
26 | return field
27 | } catch (_: NoSuchFieldException) {
28 | }
29 | }
30 | throw IllegalArgumentException(
31 | "Unable to find any of fields ${nameOptions.toList()} in ${this.name}"
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/CollectionExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import androidx.collection.ArrayMap
19 | import io.reactivex.Observable
20 |
21 | internal fun String.splitToInts(delimiter: String = ","): IntArray {
22 | return split(delimiter).map { it.toInt() }
23 | .toIntArray()
24 | }
25 |
26 | internal fun Observable.mapToIntArray(delimiter: String = ","): Observable {
27 | return map { it.splitToInts(delimiter) }
28 | }
29 |
30 | internal fun mutableArrayMap(initialCapacity: Int = 0): MutableMap {
31 | return ArrayMap(initialCapacity)
32 | }
33 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/ColorExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.graphics.Color
19 | import androidx.annotation.ColorInt
20 | import androidx.annotation.FloatRange
21 |
22 | @ColorInt internal fun Int.blendWith(
23 | @ColorInt otherColor: Int,
24 | ratio: Float
25 | ): Int {
26 | val inverseRatio = 1f - ratio
27 | val a = Color.alpha(this) * inverseRatio + Color.alpha(otherColor) * ratio
28 | val r = Color.red(this) * inverseRatio + Color.red(otherColor) * ratio
29 | val g = Color.green(this) * inverseRatio + Color.green(otherColor) * ratio
30 | val b = Color.blue(this) * inverseRatio + Color.blue(otherColor) * ratio
31 | return Color.argb(a.toInt(), r.toInt(), g.toInt(), b.toInt())
32 | }
33 |
34 | @ColorInt internal fun Int.stripAlpha(): Int {
35 | return Color.rgb(
36 | Color.red(this),
37 | Color.green(this),
38 | Color.blue(this)
39 | )
40 | }
41 |
42 | @ColorInt internal fun Int.adjustAlpha(factor: Float): Int {
43 | val alpha = Math.round(Color.alpha(this) * factor)
44 | val red = Color.red(this)
45 | val green = Color.green(this)
46 | val blue = Color.blue(this)
47 | return Color.argb(alpha, red, green, blue)
48 | }
49 |
50 | @ColorInt
51 | internal fun Int.shiftColor(
52 | @FloatRange(from = 0.0, to = 2.0) by: Float
53 | ): Int {
54 | if (by == 1f) return this
55 | val hsv = FloatArray(3)
56 | Color.colorToHSV(this, hsv)
57 | hsv[2] *= by // value component
58 | return Color.HSVToColor(hsv)
59 | }
60 |
61 | @ColorInt
62 | internal fun Int.darkenColor(): Int {
63 | return shiftColor(0.9f)
64 | }
65 |
66 | internal fun Int.isColorLight(): Boolean {
67 | if (this == Color.BLACK) {
68 | return false
69 | } else if (this == Color.WHITE || this == Color.TRANSPARENT) {
70 | return true
71 | }
72 | val darkness =
73 | 1 - (0.299 * Color.red(this) +
74 | 0.587 * Color.green(this) +
75 | 0.114 * Color.blue(this)) / 255
76 | return darkness < 0.4
77 | }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/ContextExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.graphics.drawable.Drawable
21 | import android.os.Build.VERSION.SDK_INT
22 | import android.os.Build.VERSION_CODES.P
23 | import android.util.AttributeSet
24 | import android.view.LayoutInflater
25 | import androidx.annotation.AttrRes
26 | import androidx.annotation.ColorInt
27 | import androidx.annotation.ColorRes
28 | import androidx.annotation.DrawableRes
29 | import androidx.annotation.IdRes
30 | import androidx.core.content.ContextCompat
31 | import java.lang.reflect.Array
32 | import java.lang.reflect.Field
33 |
34 | @ColorInt internal fun Context.color(@ColorRes color: Int): Int {
35 | return ContextCompat.getColor(this, color)
36 | }
37 |
38 | internal fun Context.drawable(@DrawableRes drawable: Int): Drawable? {
39 | return ContextCompat.getDrawable(this, drawable)
40 | }
41 |
42 | @ColorInt internal fun Context.colorAttr(@AttrRes attr: Int, @ColorInt fallback: Int = 0): Int {
43 | val a = theme.obtainStyledAttributes(intArrayOf(attr))
44 | return try {
45 | a.getColor(0, fallback)
46 | } catch (ignored: Throwable) {
47 | fallback
48 | } finally {
49 | a.recycle()
50 | }
51 | }
52 |
53 | @SuppressLint("Recycle")
54 | @IdRes
55 | internal fun Context.resId(
56 | attrs: AttributeSet? = null,
57 | @AttrRes attrId: Int,
58 | fallback: Int = 0
59 | ): Int {
60 | val typedArray = if (attrs != null) {
61 | obtainStyledAttributes(attrs, intArrayOf(attrId))
62 | } else {
63 | theme.obtainStyledAttributes(intArrayOf(attrId))
64 | }
65 | try {
66 | return typedArray.getResourceId(0, fallback)
67 | } finally {
68 | typedArray.recycle()
69 | }
70 | }
71 |
72 | private var mConstructorArgsField: Field? = null
73 |
74 | /**
75 | * Gets around an issue existing before API 16, or some weird 8.1 devices.
76 | *
77 | * See https://github.com/afollestad/aesthetic/issues/101 or
78 | * https://github.com/afollestad/aesthetic/issues/113
79 | */
80 | internal fun Context.fixedLayoutInflater(): LayoutInflater {
81 | val inflater = LayoutInflater.from(this)
82 | if (SDK_INT >= P) {
83 | // Don't apply fix to the latest Android versions.
84 | return inflater
85 | }
86 | if (mConstructorArgsField == null) {
87 | //mConstructorArgs
88 | mConstructorArgsField = LayoutInflater::class.findField("mConstructorArgs")
89 | }
90 | val constructorArgs = mConstructorArgsField!!.get(inflater)
91 | if (Array.get(constructorArgs, 0) == null) {
92 | Array.set(constructorArgs, 0, this)
93 | mConstructorArgsField!!.set(inflater, constructorArgs)
94 | }
95 | return inflater
96 | }
97 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/PackageManagerExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.annotation.TargetApi
19 | import android.content.pm.PackageManager
20 | import android.graphics.Bitmap
21 | import android.graphics.Canvas
22 | import android.graphics.drawable.AdaptiveIconDrawable
23 | import android.graphics.drawable.BitmapDrawable
24 | import android.graphics.drawable.LayerDrawable
25 | import android.os.Build.VERSION.SDK_INT
26 | import android.os.Build.VERSION_CODES.O
27 |
28 | @TargetApi(O)
29 | internal fun PackageManager.getAppIcon(packageName: String): Bitmap? {
30 | try {
31 | val drawable = getApplicationIcon(packageName)
32 | if (drawable is BitmapDrawable) {
33 | return drawable.bitmap
34 | } else if (SDK_INT >= O && drawable is AdaptiveIconDrawable) {
35 | val drr = arrayOf(drawable.background, drawable.foreground)
36 | val layerDrawable = LayerDrawable(drr)
37 |
38 | val width = layerDrawable.intrinsicWidth
39 | val height = layerDrawable.intrinsicHeight
40 |
41 | val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
42 | val canvas = Canvas(bitmap)
43 |
44 | layerDrawable.setBounds(0, 0, canvas.width, canvas.height)
45 | layerDrawable.draw(canvas)
46 |
47 | return bitmap
48 | }
49 | } catch (e: PackageManager.NameNotFoundException) {
50 | e.printStackTrace()
51 | }
52 |
53 | return null
54 | }
55 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/PrefsExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.content.SharedPreferences
19 |
20 | typealias PrefsEditor = SharedPreferences.Editor
21 |
22 | internal fun PrefsEditor.save(exec: PrefsEditor.() -> Unit) {
23 | this.exec()
24 | this.apply()
25 | }
26 |
27 | internal fun SharedPreferences.edit(exec: PrefsEditor.() -> Unit) {
28 | val editor = this.edit()
29 | editor.exec()
30 | editor.apply()
31 | }
32 |
33 | internal fun SharedPreferences.clear(vararg keys: String) {
34 | edit {
35 | for (key in keys) {
36 | remove(key)
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/ResourcesExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.content.res.Resources
19 | import android.util.Log
20 | import androidx.annotation.CheckResult
21 | import com.afollestad.aesthetic.BuildConfig
22 |
23 | @CheckResult
24 | internal fun Resources.safeResourceName(resId: Int): String {
25 | if (resId == 0) {
26 | return ""
27 | }
28 | return try {
29 | getResourceName(resId)
30 | } catch (_: Resources.NotFoundException) {
31 | if (BuildConfig.DEBUG) Log.w("AttrWizard", "Unable to get resource name for $resId")
32 | ""
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/RxExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import android.view.View
19 | import android.widget.ImageView
20 | import android.widget.TextView
21 | import androidx.annotation.CheckResult
22 | import androidx.cardview.widget.CardView
23 | import com.afollestad.aesthetic.blowUp
24 | import io.reactivex.Observable
25 | import io.reactivex.Observable.combineLatest
26 | import io.reactivex.ObservableSource
27 | import io.reactivex.android.schedulers.AndroidSchedulers
28 | import io.reactivex.disposables.CompositeDisposable
29 | import io.reactivex.disposables.Disposable
30 | import io.reactivex.disposables.Disposables.empty
31 | import io.reactivex.exceptions.Exceptions
32 | import io.reactivex.functions.BiFunction
33 | import io.reactivex.functions.Consumer
34 | import io.reactivex.functions.Function3
35 |
36 | typealias KotlinSubscriber = (T) -> Unit
37 |
38 | internal typealias RxMapper = (T) -> ObservableSource
39 |
40 | internal fun Observable.distinctToMainThread(): Observable {
41 | return observeOn(AndroidSchedulers.mainThread()).distinctUntilChanged()
42 | }
43 |
44 | internal operator fun CompositeDisposable?.plusAssign(disposable: Disposable) {
45 | this?.add(disposable)
46 | }
47 |
48 | internal fun onErrorLogAndRethrow(): Consumer {
49 | return Consumer { throwable ->
50 | throwable.printStackTrace()
51 | throw Exceptions.propagate(throwable)
52 | }
53 | }
54 |
55 | internal fun Observable.one(): Observable {
56 | return take(1)
57 | }
58 |
59 | internal fun Observable.toMainThread(): Observable {
60 | return observeOn(AndroidSchedulers.mainThread())
61 | }
62 |
63 | internal inline fun Observable.subscribeTo(
64 | crossinline subscriber: KotlinSubscriber
65 | ): Disposable {
66 | return this.subscribe(
67 | Consumer { subscriber(it) },
68 | onErrorLogAndRethrow()
69 | )
70 | }
71 |
72 | internal inline fun combine(
73 | source1: Observable,
74 | source2: Observable,
75 | crossinline combineFunction: (T1, T2) -> R
76 | ) = combineLatest(source1, source2, BiFunction { t1, t2 -> combineFunction(t1, t2) })!!
77 |
78 | internal fun combine(
79 | source1: Observable,
80 | source2: Observable
81 | ) = combineLatest(source1, source2, BiFunction> { t1, t2 -> t1 to t2 })!!
82 |
83 | inline fun combine(
84 | source1: Observable,
85 | source2: Observable,
86 | source3: Observable,
87 | crossinline combineFunction: (T1, T2, T3) -> R
88 | ) = combineLatest(source1, source2, source3,
89 | Function3 { t1: T1, t2: T2, t3: T3 -> combineFunction(t1, t2, t3) })!!
90 |
91 | fun Observable.subscribeBackgroundColor(view: View): Disposable {
92 | return subscribeTo {
93 | when (view) {
94 | is CardView -> view.setCardBackgroundColor(it)
95 | else -> view.setBackgroundColor(it)
96 | }
97 | }
98 | }
99 |
100 | fun Observable.subscribeTextColor(view: View): Disposable {
101 | if (view !is TextView) return empty()
102 | return subscribeTo(view::setTextColor)
103 | }
104 |
105 | fun Observable.subscribeHintTextColor(view: View): Disposable {
106 | if (view !is TextView) return empty()
107 | return subscribeTo(view::setHintTextColor)
108 | }
109 |
110 | fun Observable.subscribeImageViewTint(view: View): Disposable {
111 | if (view !is ImageView) return empty()
112 | return subscribeTo(view::setColorFilter)
113 | }
114 |
115 | /**
116 | * We use this to we don't get lint warnings when using flatMap. Since Observable.flatMap is
117 | * a Java function and does not have nullability annotations, it can "possibly be null"
118 | * (it really cannot be).
119 | */
120 | @CheckResult
121 | internal fun Observable.kFlatMap(mapper: RxMapper) = flatMap(mapper) ?: blowUp()
122 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/utils/StringExt.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.utils
17 |
18 | import androidx.annotation.CheckResult
19 |
20 | @CheckResult
21 | internal fun String.isNumber() = all { it.isDigit() }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticActionMenuItemView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.content.res.ColorStateList
21 | import android.graphics.drawable.Drawable
22 | import android.util.AttributeSet
23 | import androidx.appcompat.view.menu.ActionMenuItemView
24 | import com.afollestad.aesthetic.Aesthetic.Companion.get
25 | import com.afollestad.aesthetic.utils.adjustAlpha
26 | import com.afollestad.aesthetic.utils.one
27 | import com.afollestad.aesthetic.utils.subscribeTo
28 | import com.afollestad.aesthetic.utils.tint
29 | import com.afollestad.aesthetic.utils.toMainThread
30 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
31 |
32 | /** @author Aidan Follestad (afollestad) */
33 | @SuppressLint("RestrictedApi")
34 | internal class AestheticActionMenuItemView(
35 | context: Context,
36 | attrs: AttributeSet? = null
37 | ) : ActionMenuItemView(context, attrs) {
38 |
39 | companion object {
40 | const val UNFOCUSED_ALPHA = 0.5f
41 | }
42 |
43 | private var icon: Drawable? = null
44 |
45 | private fun invalidateColors(color: Int) {
46 | val sl = ColorStateList(
47 | arrayOf(
48 | intArrayOf(-android.R.attr.state_selected),
49 | intArrayOf(android.R.attr.state_selected)
50 | ),
51 | intArrayOf(
52 | color.adjustAlpha(UNFOCUSED_ALPHA),
53 | color
54 | )
55 | )
56 | if (icon != null) {
57 | setIcon(icon!!, sl)
58 | }
59 | setTextColor(color)
60 | }
61 |
62 | override fun setIcon(icon: Drawable) {
63 | super.setIcon(icon)
64 | // We need to retrieve the color again here.
65 | // For some reason, without this, a transparent color is used and the icon disappears
66 | // when the overflow menu opens.
67 | get().toolbarIconColor()
68 | .one()
69 | .toMainThread()
70 | .subscribeTo(::invalidateColors)
71 | .unsubscribeOnDetach(this)
72 | }
73 |
74 | @Suppress("MemberVisibilityCanBePrivate")
75 | fun setIcon(
76 | icon: Drawable,
77 | colors: ColorStateList
78 | ) {
79 | this.icon = icon
80 | super.setIcon(icon.tint(colors))
81 | }
82 |
83 | override fun onAttachedToWindow() {
84 | super.onAttachedToWindow()
85 | get().toolbarIconColor()
86 | .one()
87 | .toMainThread()
88 | .subscribeTo(::invalidateColors)
89 | .unsubscribeOnDetach(this)
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticBorderlessButton.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.content.res.ColorStateList
20 | import android.util.AttributeSet
21 | import androidx.appcompat.widget.AppCompatButton
22 | import com.afollestad.aesthetic.Aesthetic.Companion.get
23 | import com.afollestad.aesthetic.utils.adjustAlpha
24 | import com.afollestad.aesthetic.utils.distinctToMainThread
25 | import com.afollestad.aesthetic.utils.subscribeTo
26 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
27 |
28 | /** @author Aidan Follestad (afollestad) */
29 | class AestheticBorderlessButton(
30 | context: Context,
31 | attrs: AttributeSet? = null
32 | ) : AppCompatButton(context, attrs) {
33 |
34 | private fun invalidateColors(accentColor: Int) {
35 | val textColorSl = ColorStateList(
36 | arrayOf(
37 | intArrayOf(android.R.attr.state_enabled),
38 | intArrayOf(-android.R.attr.state_enabled)
39 | ),
40 | intArrayOf(
41 | accentColor,
42 | accentColor.adjustAlpha(0.56f)
43 | )
44 | )
45 | setTextColor(textColorSl)
46 |
47 | // Hack around button color not updating
48 | isEnabled = !isEnabled
49 | isEnabled = !isEnabled
50 | }
51 |
52 | override fun onAttachedToWindow() {
53 | super.onAttachedToWindow()
54 | get().colorAccent()
55 | .distinctToMainThread()
56 | .subscribeTo(::invalidateColors)
57 | .unsubscribeOnDetach(this)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticBottomAppBar.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.content.res.ColorStateList
20 | import android.graphics.drawable.Drawable
21 | import android.util.AttributeSet
22 | import androidx.annotation.ColorInt
23 | import com.afollestad.aesthetic.Aesthetic.Companion.get
24 | import com.afollestad.aesthetic.R
25 | import com.afollestad.aesthetic.internal.AttrWizard
26 | import com.afollestad.aesthetic.utils.darkenColor
27 | import com.afollestad.aesthetic.utils.observableForAttrName
28 | import com.afollestad.aesthetic.utils.setOverflowButtonColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.tint
31 | import com.afollestad.aesthetic.utils.tintMenu
32 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
33 | import com.google.android.material.bottomappbar.BottomAppBar
34 |
35 | /** @author Aidan Follestad (afollestad) */
36 | class AestheticBottomAppBar(
37 | context: Context,
38 | attrs: AttributeSet? = null
39 | ) : BottomAppBar(context, attrs) {
40 |
41 | private var menuIconColor: Int? = null
42 |
43 | private val wizard = AttrWizard(context, attrs)
44 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
45 | private val titleTextColorValue = wizard.getRawValue(R.attr.titleTextColor)
46 | private val subtitleTextColorValue = wizard.getRawValue(R.attr.subtitleTextColor)
47 |
48 | override fun setNavigationIcon(icon: Drawable?) {
49 | if (menuIconColor == null) {
50 | super.setNavigationIcon(icon)
51 | return
52 | }
53 | super.setNavigationIcon(icon.tint(menuIconColor!!))
54 | }
55 |
56 | fun setNavigationIcon(icon: Drawable?, @ColorInt color: Int) {
57 | if (menuIconColor == null) {
58 | super.setNavigationIcon(icon)
59 | return
60 | }
61 | super.setNavigationIcon(icon.tint(color))
62 | }
63 |
64 | override fun onAttachedToWindow() {
65 | super.onAttachedToWindow()
66 |
67 | get().observableForAttrName(
68 | backgroundColorValue,
69 | get().colorPrimary()
70 | )
71 | ?.distinctUntilChanged()
72 | ?.subscribeTo { backgroundTint = ColorStateList.valueOf(it) }
73 | ?.unsubscribeOnDetach(this)
74 |
75 | get().toolbarIconColor()
76 | .distinctUntilChanged()
77 | .subscribeTo(::invalidateColors)
78 | .unsubscribeOnDetach(this)
79 |
80 | get().observableForAttrName(
81 | titleTextColorValue,
82 | get().toolbarTitleColor()
83 | )
84 | ?.distinctUntilChanged()
85 | ?.subscribeTo(::setTitleTextColor)
86 | ?.unsubscribeOnDetach(this)
87 |
88 | get().observableForAttrName(
89 | subtitleTextColorValue,
90 | get().toolbarSubtitleColor()
91 | )
92 | ?.distinctUntilChanged()
93 | ?.subscribeTo(::setSubtitleTextColor)
94 | ?.unsubscribeOnDetach(this)
95 | }
96 |
97 | private fun invalidateColors(color: Int) {
98 | this.menuIconColor = color
99 | setOverflowButtonColor(color)
100 | tintMenu(menu, color, color.darkenColor())
101 | if (navigationIcon != null) {
102 | this.navigationIcon = navigationIcon
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticButton.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.content.res.ColorStateList
20 | import android.graphics.Color.BLACK
21 | import android.graphics.Color.WHITE
22 | import android.util.AttributeSet
23 | import androidx.appcompat.widget.AppCompatButton
24 | import com.afollestad.aesthetic.Aesthetic.Companion.get
25 | import com.afollestad.aesthetic.ColorIsDarkState
26 | import com.afollestad.aesthetic.internal.AttrWizard
27 | import com.afollestad.aesthetic.utils.combine
28 | import com.afollestad.aesthetic.utils.distinctToMainThread
29 | import com.afollestad.aesthetic.utils.isColorLight
30 | import com.afollestad.aesthetic.utils.observableForAttrName
31 | import com.afollestad.aesthetic.utils.setTintAuto
32 | import com.afollestad.aesthetic.utils.subscribeTo
33 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
34 |
35 | /** @author Aidan Follestad (afollestad) */
36 | class AestheticButton(
37 | context: Context,
38 | attrs: AttributeSet? = null
39 | ) : AppCompatButton(context, attrs) {
40 |
41 | private val wizard = AttrWizard(context, attrs)
42 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
43 |
44 | private fun invalidateColors(state: ColorIsDarkState) {
45 | setTintAuto(state.color, true, state.isDark)
46 | val textColorSl = ColorStateList(
47 | arrayOf(
48 | intArrayOf(android.R.attr.state_enabled),
49 | intArrayOf(-android.R.attr.state_enabled)
50 | ),
51 | intArrayOf(
52 | if (state.color.isColorLight()) BLACK else WHITE,
53 | if (state.isDark) WHITE else BLACK
54 | )
55 | )
56 | setTextColor(textColorSl)
57 |
58 | // Hack around button color not updating
59 | isEnabled = !isEnabled
60 | isEnabled = !isEnabled
61 | }
62 |
63 | override fun onAttachedToWindow() {
64 | super.onAttachedToWindow()
65 | combine(
66 | get().observableForAttrName(backgroundColorValue, get().colorAccent())!!,
67 | get().isDark
68 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
69 | .distinctToMainThread()
70 | .subscribeTo(::invalidateColors)
71 | .unsubscribeOnDetach(this)
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticCardView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.util.AttributeSet
21 | import androidx.cardview.widget.CardView
22 | import com.afollestad.aesthetic.Aesthetic.Companion.get
23 | import com.afollestad.aesthetic.R
24 | import com.afollestad.aesthetic.internal.AttrWizard
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.subscribeBackgroundColor
28 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
29 |
30 | /** @author Aidan Follestad (afollestad) */
31 | @SuppressLint("PrivateResource")
32 | class AestheticCardView(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : CardView(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(R.attr.cardBackgroundColor)
39 |
40 | override fun onAttachedToWindow() {
41 | super.onAttachedToWindow()
42 |
43 | get().observableForAttrName(
44 | backgroundColorValue,
45 | get().colorCardViewBackground()
46 | )!!
47 | .distinctToMainThread()
48 | .subscribeBackgroundColor(this)
49 | .unsubscribeOnDetach(this)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticCheckBox.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatCheckBox
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTextColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
31 |
32 | /** @author Aidan Follestad (afollestad) */
33 | class AestheticCheckBox(
34 | context: Context,
35 | attrs: AttributeSet? = null
36 | ) : AppCompatCheckBox(context, attrs) {
37 |
38 | private val wizard = AttrWizard(context, attrs)
39 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
40 |
41 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
42 |
43 | override fun onAttachedToWindow() {
44 | super.onAttachedToWindow()
45 |
46 | combine(
47 | get().observableForAttrName(
48 | backgroundColorValue,
49 | get().colorAccent()
50 | )!!,
51 | get().isDark
52 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
53 | .distinctToMainThread()
54 | .subscribeTo(::invalidateColors)
55 | .unsubscribeOnDetach(this)
56 |
57 | get().textColorPrimary()
58 | .distinctToMainThread()
59 | .subscribeTextColor(this)
60 | .unsubscribeOnDetach(this)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticCheckedTextView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatCheckedTextView
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTextColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
31 |
32 | /** @author Aidan Follestad (afollestad) */
33 | class AestheticCheckedTextView(
34 | context: Context,
35 | attrs: AttributeSet? = null
36 | ) : AppCompatCheckedTextView(context, attrs) {
37 |
38 | private val wizard = AttrWizard(context, attrs)
39 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
40 |
41 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
42 |
43 | override fun onAttachedToWindow() {
44 | super.onAttachedToWindow()
45 |
46 | combine(
47 | get().observableForAttrName(
48 | backgroundColorValue,
49 | get().colorAccent()
50 | )!!,
51 | get().isDark
52 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
53 | .distinctToMainThread()
54 | .subscribeTo(::invalidateColors)
55 | .unsubscribeOnDetach(this)
56 |
57 | get().textColorPrimary()
58 | .distinctToMainThread()
59 | .subscribeTextColor(this)
60 | .unsubscribeOnDetach(this)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticDialogButton.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatButton
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.distinctToMainThread
23 | import com.afollestad.aesthetic.utils.subscribeTextColor
24 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
25 |
26 | /** @author Aidan Follestad (afollestad) */
27 | internal class AestheticDialogButton(
28 | context: Context,
29 | attrs: AttributeSet? = null
30 | ) : AppCompatButton(context, attrs) {
31 |
32 | override fun onAttachedToWindow() {
33 | super.onAttachedToWindow()
34 | get().colorAccent()
35 | .distinctToMainThread()
36 | .subscribeTextColor(this)
37 | .unsubscribeOnDetach(this)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticDrawerLayout.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.app.ActionBarDrawerToggle
21 | import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
22 | import androidx.drawerlayout.widget.DrawerLayout
23 | import com.afollestad.aesthetic.Aesthetic.Companion.get
24 | import com.afollestad.aesthetic.utils.distinctToMainThread
25 | import com.afollestad.aesthetic.utils.subscribeTo
26 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
27 |
28 | /** @author Aidan Follestad (afollestad) */
29 | class AestheticDrawerLayout(
30 | context: Context,
31 | attrs: AttributeSet? = null
32 | ) : DrawerLayout(context, attrs) {
33 |
34 | private var lastColor: Int? = null
35 | private var arrowDrawable: DrawerArrowDrawable? = null
36 |
37 | private fun invalidateColor(color: Int?) {
38 | if (color == null) {
39 | return
40 | }
41 | this.lastColor = color
42 | this.arrowDrawable?.color = color
43 | }
44 |
45 | override fun onAttachedToWindow() {
46 | super.onAttachedToWindow()
47 | get().toolbarIconColor()
48 | .distinctToMainThread()
49 | .subscribeTo(::invalidateColor)
50 | .unsubscribeOnDetach(this)
51 | }
52 |
53 | override fun addDrawerListener(listener: DrawerLayout.DrawerListener) {
54 | super.addDrawerListener(listener)
55 | if (listener is ActionBarDrawerToggle) {
56 | this.arrowDrawable = listener.drawerArrowDrawable
57 | }
58 | invalidateColor(lastColor)
59 | }
60 |
61 | @Suppress("OverridingDeprecatedMember", "DEPRECATION")
62 | override fun setDrawerListener(listener: DrawerLayout.DrawerListener) {
63 | super.setDrawerListener(listener)
64 | if (listener is ActionBarDrawerToggle) {
65 | this.arrowDrawable = listener.drawerArrowDrawable
66 | }
67 | invalidateColor(lastColor)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticEditText.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.util.AttributeSet
21 | import androidx.appcompat.widget.AppCompatEditText
22 | import com.afollestad.aesthetic.Aesthetic.Companion.get
23 | import com.afollestad.aesthetic.ColorIsDarkState
24 | import com.afollestad.aesthetic.R
25 | import com.afollestad.aesthetic.internal.AttrWizard
26 | import com.afollestad.aesthetic.utils.combine
27 | import com.afollestad.aesthetic.utils.distinctToMainThread
28 | import com.afollestad.aesthetic.utils.observableForAttrName
29 | import com.afollestad.aesthetic.utils.setTintAuto
30 | import com.afollestad.aesthetic.utils.subscribeHintTextColor
31 | import com.afollestad.aesthetic.utils.subscribeTextColor
32 | import com.afollestad.aesthetic.utils.subscribeTo
33 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
34 |
35 | /** @author Aidan Follestad (afollestad) */
36 | @SuppressLint("ResourceType")
37 | class AestheticEditText(
38 | context: Context,
39 | attrs: AttributeSet? = null
40 | ) : AppCompatEditText(context, attrs) {
41 |
42 | private val wizard = AttrWizard(context, attrs)
43 | private val tintColorValue = wizard.getRawValue(R.attr.tint)
44 | private val textColorValue = wizard.getRawValue(android.R.attr.textColor)
45 | private val textColorHintValue = wizard.getRawValue(android.R.attr.textColorHint)
46 |
47 | private fun invalidateColors(state: ColorIsDarkState) =
48 | setTintAuto(state.color, true, state.isDark)
49 |
50 | override fun onAttachedToWindow() {
51 | super.onAttachedToWindow()
52 |
53 | combine(
54 | get().observableForAttrName(
55 | tintColorValue,
56 | get().colorAccent()
57 | )!!,
58 | get().isDark
59 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
60 | .distinctToMainThread()
61 | .subscribeTo(::invalidateColors)
62 | .unsubscribeOnDetach(this)
63 |
64 | get().observableForAttrName(
65 | textColorValue,
66 | get().textColorPrimary()
67 | )!!
68 | .distinctToMainThread()
69 | .subscribeTextColor(this)
70 | .unsubscribeOnDetach(this)
71 |
72 | get().observableForAttrName(
73 | textColorHintValue,
74 | get().textColorSecondary()
75 | )!!
76 | .distinctToMainThread()
77 | .subscribeHintTextColor(this)
78 | .unsubscribeOnDetach(this)
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticFab.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.graphics.Color.BLACK
20 | import android.graphics.Color.WHITE
21 | import android.graphics.drawable.Drawable
22 | import android.util.AttributeSet
23 | import com.afollestad.aesthetic.Aesthetic.Companion.get
24 | import com.afollestad.aesthetic.ColorIsDarkState
25 | import com.afollestad.aesthetic.internal.AttrWizard
26 | import com.afollestad.aesthetic.utils.combine
27 | import com.afollestad.aesthetic.utils.distinctToMainThread
28 | import com.afollestad.aesthetic.utils.isColorLight
29 | import com.afollestad.aesthetic.utils.observableForAttrName
30 | import com.afollestad.aesthetic.utils.setTintAuto
31 | import com.afollestad.aesthetic.utils.subscribeTo
32 | import com.afollestad.aesthetic.utils.tint
33 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
34 | import com.google.android.material.floatingactionbutton.FloatingActionButton
35 |
36 | /** @author Aidan Follestad (afollestad) */
37 | class AestheticFab(
38 | context: Context,
39 | attrs: AttributeSet? = null
40 | ) : FloatingActionButton(context, attrs) {
41 |
42 | private val wizard = AttrWizard(context, attrs)
43 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
44 | private var iconColor: Int = 0
45 |
46 | private fun invalidateColors(state: ColorIsDarkState) {
47 | setTintAuto(state.color, true, state.isDark)
48 | iconColor = if (state.color.isColorLight()) BLACK else WHITE
49 | setImageDrawable(drawable)
50 | }
51 |
52 | override fun setImageDrawable(drawable: Drawable?) =
53 | super.setImageDrawable(drawable?.tint(iconColor))
54 |
55 | override fun onAttachedToWindow() {
56 | super.onAttachedToWindow()
57 |
58 | combine(
59 | get().observableForAttrName(
60 | backgroundColorValue,
61 | get().colorAccent()
62 | )!!,
63 | get().isDark
64 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
65 | .distinctToMainThread()
66 | .subscribeTo(::invalidateColors)
67 | .unsubscribeOnDetach(this)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticListView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import android.widget.ListView
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.EdgeGlowUtil.setEdgeGlowColor
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticListView(
29 | context: Context,
30 | attrs: AttributeSet? = null
31 | ) : ListView(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) =
34 | setEdgeGlowColor(this, color)
35 |
36 | override fun onAttachedToWindow() {
37 | super.onAttachedToWindow()
38 | get().colorAccent()
39 | .distinctToMainThread()
40 | .subscribeTo(::invalidateColors)
41 | .unsubscribeOnDetach(this)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticNavigationView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.content.res.ColorStateList
21 | import android.graphics.Color
22 | import android.graphics.drawable.ColorDrawable
23 | import android.graphics.drawable.StateListDrawable
24 | import android.util.AttributeSet
25 | import com.afollestad.aesthetic.Aesthetic.Companion.get
26 | import com.afollestad.aesthetic.ColorIsDarkState
27 | import com.afollestad.aesthetic.NavigationViewMode.NONE
28 | import com.afollestad.aesthetic.NavigationViewMode.SELECTED_ACCENT
29 | import com.afollestad.aesthetic.NavigationViewMode.SELECTED_PRIMARY
30 | import com.afollestad.aesthetic.R
31 | import com.afollestad.aesthetic.utils.adjustAlpha
32 | import com.afollestad.aesthetic.utils.color
33 | import com.afollestad.aesthetic.utils.combine
34 | import com.afollestad.aesthetic.utils.distinctToMainThread
35 | import com.afollestad.aesthetic.utils.subscribeTo
36 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
37 | import com.google.android.material.navigation.NavigationView
38 | import io.reactivex.Observable.empty
39 | import io.reactivex.disposables.Disposable
40 |
41 | /** @author Aidan Follestad (afollestad) */
42 | @SuppressLint("RestrictedApi")
43 | class AestheticNavigationView(
44 | context: Context,
45 | attrs: AttributeSet? = null
46 | ) : NavigationView(context, attrs) {
47 |
48 | private var colorSubscription: Disposable? = null
49 |
50 | private fun invalidateColors(state: ColorIsDarkState) {
51 | val selectedColor = state.color
52 | val isDark = state.isDark
53 | val baseColor = if (isDark) Color.WHITE else Color.BLACK
54 | val unselectedIconColor = baseColor.adjustAlpha(.54f)
55 | val unselectedTextColor = baseColor.adjustAlpha(.87f)
56 |
57 | val selectedItemBgColor = context.color(
58 | if (isDark) R.color.ate_navigation_drawer_selected_dark
59 | else R.color.ate_navigation_drawer_selected_light
60 | )
61 |
62 | val iconSl = ColorStateList(
63 | arrayOf(
64 | intArrayOf(-android.R.attr.state_checked),
65 | intArrayOf(android.R.attr.state_checked)
66 | ),
67 | intArrayOf(unselectedIconColor, selectedColor)
68 | )
69 | val textSl = ColorStateList(
70 | arrayOf(
71 | intArrayOf(-android.R.attr.state_checked),
72 | intArrayOf(android.R.attr.state_checked)
73 | ),
74 | intArrayOf(unselectedTextColor, selectedColor)
75 | )
76 |
77 | itemTextColor = textSl
78 | itemIconTintList = iconSl
79 |
80 | val bgDrawable = StateListDrawable()
81 | bgDrawable.addState(
82 | intArrayOf(android.R.attr.state_checked),
83 | ColorDrawable(selectedItemBgColor)
84 | )
85 | itemBackground = bgDrawable
86 | }
87 |
88 | override fun onAttachedToWindow() {
89 | super.onAttachedToWindow()
90 | get().navigationViewMode()
91 | .distinctToMainThread()
92 | .flatMap {
93 | when (it) {
94 | SELECTED_PRIMARY -> combine(
95 | get().colorPrimary(),
96 | get().isDark
97 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
98 |
99 | SELECTED_ACCENT -> combine(
100 | get().colorAccent(),
101 | get().isDark
102 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
103 |
104 | NONE -> empty()
105 | }
106 | }
107 | .distinctUntilChanged()
108 | .subscribeTo(::invalidateColors)
109 | .unsubscribeOnDetach(this)
110 | }
111 |
112 | override fun onDetachedFromWindow() {
113 | colorSubscription?.dispose()
114 | super.onDetachedFromWindow()
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticNestedScrollView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.core.widget.NestedScrollView
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.EdgeGlowUtil.setEdgeGlowColor
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticNestedScrollView(
29 | context: Context,
30 | attrs: AttributeSet? = null
31 | ) : NestedScrollView(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) =
34 | setEdgeGlowColor(this, color)
35 |
36 | override fun onAttachedToWindow() {
37 | super.onAttachedToWindow()
38 | get().colorAccent()
39 | .distinctToMainThread()
40 | .subscribeTo(::invalidateColors)
41 | .unsubscribeOnDetach(this)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticProgressBar.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import android.widget.ProgressBar
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.distinctToMainThread
23 | import com.afollestad.aesthetic.utils.setTint
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticProgressBar(
29 | context: Context?,
30 | attrs: AttributeSet? = null
31 | ) : ProgressBar(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) = setTint(color)
34 |
35 | override fun onAttachedToWindow() {
36 | super.onAttachedToWindow()
37 | get().colorAccent()
38 | .distinctToMainThread()
39 | .subscribeTo(::invalidateColors)
40 | .unsubscribeOnDetach(this)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticRadioButton.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatRadioButton
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTextColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
31 |
32 | /** @author Aidan Follestad (afollestad) */
33 | class AestheticRadioButton(
34 | context: Context,
35 | attrs: AttributeSet? = null
36 | ) : AppCompatRadioButton(context, attrs) {
37 |
38 | private val wizard = AttrWizard(context, attrs)
39 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
40 |
41 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
42 |
43 | override fun onAttachedToWindow() {
44 | super.onAttachedToWindow()
45 |
46 | combine(
47 | get().observableForAttrName(
48 | backgroundColorValue,
49 | get().colorAccent()
50 | )!!,
51 | get().isDark
52 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
53 | .distinctToMainThread()
54 | .subscribeTo(::invalidateColors)
55 | .unsubscribeOnDetach(this)
56 |
57 | get().textColorPrimary()
58 | .distinctToMainThread()
59 | .subscribeTextColor(this)
60 | .unsubscribeOnDetach(this)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticRatingBar.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatRatingBar
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTo
29 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticRatingBar(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : AppCompatRatingBar(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 |
45 | combine(
46 | get().observableForAttrName(
47 | backgroundColorValue,
48 | get().colorAccent()
49 | )!!,
50 | get().isDark
51 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
52 | .distinctToMainThread()
53 | .subscribeTo(::invalidateColors)
54 | .unsubscribeOnDetach(this)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticRecyclerView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.recyclerview.widget.RecyclerView
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.EdgeGlowUtil.setEdgeGlowColor
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticRecyclerView(
29 | context: Context,
30 | attrs: AttributeSet? = null
31 | ) : RecyclerView(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) =
34 | setEdgeGlowColor(this, color, null)
35 |
36 | override fun onAttachedToWindow() {
37 | super.onAttachedToWindow()
38 | get().colorAccent()
39 | .distinctToMainThread()
40 | .subscribeTo(::invalidateColors)
41 | .unsubscribeOnDetach(this)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticScrollView.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import android.widget.ScrollView
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.EdgeGlowUtil.setEdgeGlowColor
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticScrollView(
29 | context: Context?,
30 | attrs: AttributeSet? = null
31 | ) : ScrollView(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) =
34 | setEdgeGlowColor(this, color)
35 |
36 | override fun onAttachedToWindow() {
37 | super.onAttachedToWindow()
38 | get().colorAccent()
39 | .distinctToMainThread()
40 | .subscribeTo(::invalidateColors)
41 | .unsubscribeOnDetach(this)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSeekBar.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatSeekBar
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTo
29 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticSeekBar(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : AppCompatSeekBar(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 |
45 | combine(
46 | get().observableForAttrName(
47 | backgroundColorValue,
48 | get().colorAccent()
49 | )!!,
50 | get().isDark
51 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
52 | .distinctToMainThread()
53 | .subscribeTo(::invalidateColors)
54 | .unsubscribeOnDetach(this)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSnackBarContentLayout.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.util.AttributeSet
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.distinctToMainThread
23 | import com.afollestad.aesthetic.utils.subscribeTextColor
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.tint
26 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
27 | import com.google.android.material.snackbar.Snackbar
28 | import com.google.android.material.snackbar.SnackbarContentLayout
29 |
30 | /** @author Aidan Follestad (afollestad) */
31 | @SuppressLint("RestrictedApi")
32 | internal class AestheticSnackBarContentLayout(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : SnackbarContentLayout(context, attrs) {
36 |
37 | override fun onAttachedToWindow() {
38 | super.onAttachedToWindow()
39 |
40 | get().snackbarBackgroundColor()
41 | .distinctToMainThread()
42 | .subscribeTo(this::invalidateBgColors)
43 | .unsubscribeOnDetach(this)
44 |
45 | get().snackbarTextColor()
46 | .distinctToMainThread()
47 | .subscribeTextColor(messageView)
48 | .unsubscribeOnDetach(this)
49 |
50 | get().snackbarActionTextColor()
51 | .distinctToMainThread()
52 | .subscribeTextColor(actionView)
53 | .unsubscribeOnDetach(this)
54 | }
55 |
56 | private fun invalidateBgColors(color: Int) {
57 | setBackgroundColor(color)
58 | val parent = this.parent
59 | if (parent is Snackbar.SnackbarLayout) {
60 | val background = parent.background
61 | if (background != null) {
62 | parent.background = background.tint(color)
63 | } else {
64 | parent.setBackgroundColor(color)
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSpinner.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.AppCompatSpinner
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTintAuto
28 | import com.afollestad.aesthetic.utils.subscribeTo
29 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticSpinner(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : AppCompatSpinner(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(state: ColorIsDarkState) =
41 | setTintAuto(state.color, true, state.isDark)
42 |
43 | override fun onAttachedToWindow() {
44 | super.onAttachedToWindow()
45 |
46 | combine(
47 | get().observableForAttrName(
48 | backgroundColorValue,
49 | get().colorAccent()
50 | )!!,
51 | get().isDark
52 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
53 | .distinctToMainThread()
54 | .subscribeTo(::invalidateColors)
55 | .unsubscribeOnDetach(this)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSwipeRefreshLayout.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.util.AttributeSet
21 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
22 | import com.afollestad.aesthetic.Aesthetic.Companion.get
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | @SuppressLint("PrivateResource")
29 | class AestheticSwipeRefreshLayout(
30 | context: Context,
31 | attrs: AttributeSet? = null
32 | ) : SwipeRefreshLayout(context, attrs) {
33 |
34 | override fun onAttachedToWindow() {
35 | super.onAttachedToWindow()
36 | get().swipeRefreshLayoutColors()
37 | .distinctToMainThread()
38 | .subscribeTo(::setColorSchemeColors)
39 | .unsubscribeOnDetach(this)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSwitch.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import android.widget.Switch
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTo
29 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticSwitch(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : Switch(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 |
45 | combine(
46 | get().observableForAttrName(
47 | backgroundColorValue,
48 | get().colorAccent()
49 | )!!,
50 | get().isDark
51 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
52 | .distinctToMainThread()
53 | .subscribeTo(::invalidateColors)
54 | .unsubscribeOnDetach(this)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticSwitchCompat.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.appcompat.widget.SwitchCompat
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.ColorIsDarkState
23 | import com.afollestad.aesthetic.internal.AttrWizard
24 | import com.afollestad.aesthetic.utils.combine
25 | import com.afollestad.aesthetic.utils.distinctToMainThread
26 | import com.afollestad.aesthetic.utils.observableForAttrName
27 | import com.afollestad.aesthetic.utils.setTint
28 | import com.afollestad.aesthetic.utils.subscribeTo
29 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticSwitchCompat(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : SwitchCompat(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(state: ColorIsDarkState) = setTint(state.color, state.isDark)
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 |
45 | combine(
46 | get().observableForAttrName(
47 | backgroundColorValue,
48 | get().colorAccent()
49 | )!!,
50 | get().isDark
51 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
52 | .distinctToMainThread()
53 | .subscribeTo(::invalidateColors)
54 | .unsubscribeOnDetach(this)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticTabLayout.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import android.content.res.ColorStateList
21 | import android.util.AttributeSet
22 | import androidx.annotation.ColorInt
23 | import com.afollestad.aesthetic.Aesthetic.Companion.get
24 | import com.afollestad.aesthetic.ColorMode
25 | import com.afollestad.aesthetic.utils.adjustAlpha
26 | import com.afollestad.aesthetic.utils.distinctToMainThread
27 | import com.afollestad.aesthetic.utils.one
28 | import com.afollestad.aesthetic.utils.subscribeBackgroundColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.tint
31 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
32 | import com.google.android.material.tabs.TabLayout
33 |
34 | /** @author Aidan Follestad (afollestad) */
35 | class AestheticTabLayout(
36 | context: Context,
37 | attrs: AttributeSet? = null
38 | ) : TabLayout(context, attrs) {
39 |
40 | companion object {
41 | const val UNFOCUSED_ALPHA = 0.5f
42 | }
43 |
44 | @SuppressLint("CheckResult")
45 | override fun setBackgroundColor(@ColorInt color: Int) {
46 | super.setBackgroundColor(color)
47 | get().toolbarIconColor()
48 | .one()
49 | .subscribeTo(::setIconsColor)
50 | .unsubscribeOnDetach(this)
51 | get().toolbarTitleColor()
52 | .one()
53 | .subscribeTo { setTabTextColors(it.adjustAlpha(UNFOCUSED_ALPHA), it) }
54 | .unsubscribeOnDetach(this)
55 | }
56 |
57 | override fun onAttachedToWindow() {
58 | super.onAttachedToWindow()
59 |
60 | get().toolbarIconColor()
61 | .subscribeTo(::setIconsColor)
62 | .unsubscribeOnDetach(this)
63 |
64 | get().toolbarTitleColor()
65 | .subscribeTo { setTabTextColors(it.adjustAlpha(UNFOCUSED_ALPHA), it) }
66 | .unsubscribeOnDetach(this)
67 |
68 | get().tabLayoutBackgroundMode()
69 | .distinctToMainThread()
70 | .flatMap {
71 | when (it) {
72 | ColorMode.PRIMARY -> get().colorPrimary()
73 | ColorMode.ACCENT -> get().colorAccent()
74 | }
75 | }
76 | .distinctToMainThread()
77 | .subscribeBackgroundColor(this@AestheticTabLayout)
78 | .unsubscribeOnDetach(this)
79 |
80 | get().tabLayoutIndicatorMode()
81 | .distinctToMainThread()
82 | .flatMap {
83 | when (it) {
84 | ColorMode.PRIMARY -> get().colorPrimary()
85 | ColorMode.ACCENT -> get().colorAccent()
86 | }
87 | }
88 | .distinctToMainThread()
89 | .subscribeTo(::setSelectedTabIndicatorColor)
90 | .unsubscribeOnDetach(this)
91 | }
92 |
93 | private fun setIconsColor(color: Int) {
94 | val sl = ColorStateList(
95 | arrayOf(
96 | intArrayOf(-android.R.attr.state_selected),
97 | intArrayOf(android.R.attr.state_selected)
98 | ),
99 | intArrayOf(
100 | color.adjustAlpha(UNFOCUSED_ALPHA),
101 | color
102 | )
103 | )
104 | for (i in 0 until tabCount) {
105 | val tab = getTabAt(i)
106 | if (tab != null && tab.icon != null) {
107 | tab.icon = tab.icon.tint(sl)
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticTextInputEditText.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import com.afollestad.aesthetic.Aesthetic.Companion.get
21 | import com.afollestad.aesthetic.ColorIsDarkState
22 | import com.afollestad.aesthetic.internal.AttrWizard
23 | import com.afollestad.aesthetic.utils.combine
24 | import com.afollestad.aesthetic.utils.distinctToMainThread
25 | import com.afollestad.aesthetic.utils.observableForAttrName
26 | import com.afollestad.aesthetic.utils.setTintAuto
27 | import com.afollestad.aesthetic.utils.subscribeHintTextColor
28 | import com.afollestad.aesthetic.utils.subscribeTextColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
31 | import com.google.android.material.textfield.TextInputEditText
32 |
33 | /** @author Aidan Follestad (afollestad) */
34 | class AestheticTextInputEditText(
35 | context: Context,
36 | attrs: AttributeSet? = null
37 | ) : TextInputEditText(context, attrs) {
38 |
39 | private var lastState: ColorIsDarkState? = null
40 | private val wizard = AttrWizard(context, attrs)
41 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
42 |
43 | private fun invalidateColors(state: ColorIsDarkState) {
44 | this.lastState = state
45 | setTintAuto(state.color, true, state.isDark)
46 | }
47 |
48 | override fun onAttachedToWindow() {
49 | super.onAttachedToWindow()
50 |
51 | get().textColorPrimary()
52 | .distinctToMainThread()
53 | .subscribeTextColor(this)
54 | .unsubscribeOnDetach(this)
55 |
56 | get().textColorSecondary()
57 | .distinctToMainThread()
58 | .subscribeHintTextColor(this)
59 | .unsubscribeOnDetach(this)
60 |
61 | combine(
62 | get().observableForAttrName(
63 | backgroundColorValue,
64 | get().colorAccent()
65 | )!!,
66 | get().isDark
67 | ) { color, isDark -> ColorIsDarkState(color, isDark) }
68 | .distinctToMainThread()
69 | .subscribeTo(::invalidateColors)
70 | .unsubscribeOnDetach(this)
71 | }
72 |
73 | override fun refreshDrawableState() {
74 | super.refreshDrawableState()
75 | if (lastState != null) {
76 | post { invalidateColors(lastState!!) }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticTextInputLayout.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import com.afollestad.aesthetic.Aesthetic.Companion.get
21 | import com.afollestad.aesthetic.internal.AttrWizard
22 | import com.afollestad.aesthetic.utils.adjustAlpha
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.observableForAttrName
25 | import com.afollestad.aesthetic.utils.setAccentColor
26 | import com.afollestad.aesthetic.utils.setHintColor
27 | import com.afollestad.aesthetic.utils.subscribeTo
28 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
29 | import com.google.android.material.textfield.TextInputLayout
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AestheticTextInputLayout(
33 | context: Context,
34 | attrs: AttributeSet? = null
35 | ) : TextInputLayout(context, attrs) {
36 |
37 | private val wizard = AttrWizard(context, attrs)
38 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
39 |
40 | private fun invalidateColors(color: Int) = setAccentColor(color)
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 |
45 | get().textColorSecondary()
46 | .distinctToMainThread()
47 | .subscribeTo { setHintColor(it.adjustAlpha(0.7f)) }
48 | .unsubscribeOnDetach(this)
49 |
50 | get().observableForAttrName(
51 | backgroundColorValue,
52 | get().colorAccent()
53 | )!!
54 | .distinctToMainThread()
55 | .subscribeTo(::invalidateColors)
56 | .unsubscribeOnDetach(this)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticToolbar.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.graphics.drawable.Drawable
20 | import android.util.AttributeSet
21 | import androidx.annotation.ColorInt
22 | import androidx.appcompat.widget.Toolbar
23 | import com.afollestad.aesthetic.Aesthetic.Companion.get
24 | import com.afollestad.aesthetic.R
25 | import com.afollestad.aesthetic.internal.AttrWizard
26 | import com.afollestad.aesthetic.utils.darkenColor
27 | import com.afollestad.aesthetic.utils.observableForAttrName
28 | import com.afollestad.aesthetic.utils.setOverflowButtonColor
29 | import com.afollestad.aesthetic.utils.subscribeTo
30 | import com.afollestad.aesthetic.utils.tint
31 | import com.afollestad.aesthetic.utils.tintMenu
32 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
33 | import io.reactivex.subjects.PublishSubject
34 |
35 | /** @author Aidan Follestad (afollestad) */
36 | class AestheticToolbar(
37 | context: Context,
38 | attrs: AttributeSet? = null
39 | ) : Toolbar(context, attrs) {
40 |
41 | private var onColorUpdated = PublishSubject.create()
42 | private var menuIconColor: Int? = null
43 |
44 | private val wizard = AttrWizard(context, attrs)
45 | private val backgroundColorValue = wizard.getRawValue(android.R.attr.background)
46 | private val titleTextColorValue = wizard.getRawValue(R.attr.titleTextColor)
47 | private val subtitleTextColorValue = wizard.getRawValue(R.attr.subtitleTextColor)
48 |
49 | fun colorUpdated() = onColorUpdated
50 |
51 | override fun setNavigationIcon(icon: Drawable?) {
52 | if (menuIconColor == null) {
53 | super.setNavigationIcon(icon)
54 | return
55 | }
56 | super.setNavigationIcon(icon.tint(menuIconColor!!))
57 | }
58 |
59 | fun setNavigationIcon(icon: Drawable?, @ColorInt color: Int) {
60 | if (menuIconColor == null) {
61 | super.setNavigationIcon(icon)
62 | return
63 | }
64 | super.setNavigationIcon(icon.tint(color))
65 | }
66 |
67 | override fun onAttachedToWindow() {
68 | super.onAttachedToWindow()
69 |
70 | get().observableForAttrName(
71 | backgroundColorValue,
72 | get().colorPrimary()
73 | )!!
74 | .distinctUntilChanged()
75 | .doOnNext { onColorUpdated.onNext(it) }
76 | .subscribeTo(::setBackgroundColor)
77 | .unsubscribeOnDetach(this)
78 |
79 | get().toolbarIconColor()
80 | .distinctUntilChanged()
81 | .subscribeTo(::invalidateColors)
82 | .unsubscribeOnDetach(this)
83 |
84 | get().observableForAttrName(
85 | titleTextColorValue,
86 | get().toolbarTitleColor()
87 | )
88 | ?.distinctUntilChanged()
89 | ?.subscribeTo(::setTitleTextColor)
90 | ?.unsubscribeOnDetach(this)
91 |
92 | get().observableForAttrName(
93 | subtitleTextColorValue,
94 | get().toolbarSubtitleColor()
95 | )
96 | ?.distinctUntilChanged()
97 | ?.subscribeTo(::setSubtitleTextColor)
98 | ?.unsubscribeOnDetach(this)
99 | }
100 |
101 | private fun invalidateColors(color: Int) {
102 | this.menuIconColor = color
103 | setOverflowButtonColor(color)
104 | tintMenu(menu, color, color.darkenColor())
105 | if (navigationIcon != null) {
106 | this.navigationIcon = navigationIcon
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/library/src/main/java/com/afollestad/aesthetic/views/AestheticViewPager.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aesthetic.views
17 |
18 | import android.content.Context
19 | import android.util.AttributeSet
20 | import androidx.viewpager.widget.ViewPager
21 | import com.afollestad.aesthetic.Aesthetic.Companion.get
22 | import com.afollestad.aesthetic.utils.EdgeGlowUtil.setEdgeGlowColor
23 | import com.afollestad.aesthetic.utils.distinctToMainThread
24 | import com.afollestad.aesthetic.utils.subscribeTo
25 | import com.afollestad.aesthetic.utils.unsubscribeOnDetach
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class AestheticViewPager(
29 | context: Context,
30 | attrs: AttributeSet? = null
31 | ) : ViewPager(context, attrs) {
32 |
33 | private fun invalidateColors(color: Int) =
34 | setEdgeGlowColor(this, color)
35 |
36 | override fun onAttachedToWindow() {
37 | super.onAttachedToWindow()
38 | get().colorAccent()
39 | .distinctToMainThread()
40 | .subscribeTo(::invalidateColors)
41 | .unsubscribeOnDetach(this)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/res-public/values/public.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | #1F000000
8 | #1F000000
9 |
10 | #43000000
11 | #43000000
12 | #43000000
13 |
14 | #61000000
15 |
16 | #8A000000
17 |
18 | #61000000
19 | #8A000000
20 |
21 | #DE000000
22 |
23 | #FFFAFAFA
24 |
25 | #FFBDBDBD
26 |
27 | #E8E8E8
28 | #F5F5F5
29 | #FFFFFF
30 |
31 |
32 |
33 | #1AFFFFFF
34 |
35 | #1F000000
36 |
37 | #4DFFFFFF
38 | #4DFFFFFF
39 | #4DFFFFFF
40 | #4DFFFFFF
41 |
42 | #ffffffff
43 |
44 | #80FFFFFF
45 | #B3FFFFFF
46 |
47 | #FFFFFFFF
48 |
49 | #FFBDBDBD
50 |
51 | #FF424242
52 |
53 | #202020
54 | #424242
55 | #424242
56 |
57 |
--------------------------------------------------------------------------------
/library/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/sample-appcompat/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample-appcompat/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: '../dependencies.gradle'
2 | apply plugin: 'com.android.application'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'kotlin-kapt'
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion versions.compileSdk
9 | buildToolsVersion versions.buildTools
10 |
11 | defaultConfig {
12 | applicationId "com.afollestad.aestheticsample.appcompat"
13 | minSdkVersion versions.minSdk
14 | targetSdkVersion versions.compileSdk
15 | versionCode versions.publishVersionCode
16 | versionName versions.publishVersion
17 | vectorDrawables.useSupportLibrary = true
18 | }
19 |
20 | compileOptions {
21 | kotlinOptions.freeCompilerArgs += ['-module-name', "com.afollestad.aestheticsample.appcompat"]
22 | }
23 |
24 | packagingOptions {
25 | pickFirst 'META-INF/proguard/androidx-annotations.pro'
26 | }
27 | }
28 |
29 | repositories {
30 | google()
31 | jcenter()
32 | }
33 |
34 | dependencies {
35 | implementation project(':library')
36 |
37 | implementation 'androidx.preference:preference:' + versions.androidx
38 | implementation 'com.google.android.material:material:' + versions.androidx
39 |
40 | implementation 'io.reactivex.rxjava2:rxjava:' + versions.rxJava
41 | implementation 'io.reactivex.rxjava2:rxandroid:' + versions.rxAndroid
42 |
43 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
44 | }
45 |
46 | apply from: '../spotless.gradle'
--------------------------------------------------------------------------------
/sample-appcompat/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
33 |
36 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/AppCompatDemoActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.content.Intent
19 | import android.graphics.Color
20 | import android.os.Bundle
21 | import androidx.appcompat.widget.SearchView
22 | import com.afollestad.aesthetic.Aesthetic
23 | import com.afollestad.aesthetic.AestheticActivity
24 | import com.afollestad.aesthetic.BottomNavBgMode
25 | import com.afollestad.aesthetic.BottomNavIconTextMode
26 | import com.afollestad.aesthetic.NavigationViewMode
27 | import kotlinx.android.synthetic.main.activity_demo_appcompat.pager
28 | import kotlinx.android.synthetic.main.activity_demo_appcompat.tabs
29 | import kotlinx.android.synthetic.main.activity_demo_appcompat.toolbar
30 |
31 | /** @author Aidan Follestad (afollestad) */
32 | class AppCompatDemoActivity : AestheticActivity() {
33 |
34 | override fun onCreate(savedInstanceState: Bundle?) {
35 | super.onCreate(savedInstanceState)
36 | setContentView(R.layout.activity_demo_appcompat)
37 |
38 | toolbar.inflateMenu(R.menu.main)
39 | toolbar.setOnMenuItemClickListener {
40 | if (it.itemId == R.id.settings) {
41 | startActivity(Intent(this@AppCompatDemoActivity, SettingsActivity::class.java))
42 | }
43 | true
44 | }
45 |
46 | val searchItem = toolbar.menu.findItem(R.id.search)
47 | val searchView = searchItem.actionView as SearchView
48 | searchView.queryHint = getString(R.string.search_view_example)
49 |
50 | // If we haven't set any defaults, do that now
51 | if (Aesthetic.isFirstTime) {
52 | Aesthetic.config {
53 | activityTheme(R.style.AppCompatDemoTheme)
54 | textColorPrimary(res = R.color.text_color_primary)
55 | textColorSecondary(res = R.color.text_color_secondary)
56 | colorPrimary(res = R.color.md_white)
57 | colorAccent(res = R.color.md_blue)
58 | colorStatusBarAuto()
59 | colorNavigationBarAuto()
60 | textColorPrimary(Color.BLACK)
61 | navigationViewMode(NavigationViewMode.SELECTED_ACCENT)
62 | bottomNavigationBackgroundMode(BottomNavBgMode.PRIMARY)
63 | bottomNavigationIconTextMode(BottomNavIconTextMode.SELECTED_ACCENT)
64 | swipeRefreshLayoutColorsRes(
65 | R.color.md_blue,
66 | R.color.md_blue_grey,
67 | R.color.md_green
68 | )
69 | attribute(R.attr.my_custom_attr, res = R.color.md_red)
70 | }
71 | }
72 |
73 | pager.adapter =
74 | MainPagerAdapter(this, supportFragmentManager)
75 | tabs.setupWithViewPager(pager)
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/DrawerActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.content.res.Configuration
19 | import android.os.Bundle
20 | import android.view.MenuItem
21 | import androidx.appcompat.app.ActionBarDrawerToggle
22 | import com.afollestad.aesthetic.AestheticActivity
23 | import kotlinx.android.synthetic.main.activity_drawer.drawer_layout
24 | import kotlinx.android.synthetic.main.activity_drawer.navigation_view
25 | import kotlinx.android.synthetic.main.activity_drawer.toolbar
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | class DrawerActivity : AestheticActivity() {
29 |
30 | private lateinit var drawerToggle: ActionBarDrawerToggle
31 |
32 | override fun onCreate(savedInstanceState: Bundle?) {
33 | super.onCreate(savedInstanceState)
34 | setContentView(R.layout.activity_drawer)
35 | setSupportActionBar(toolbar)
36 |
37 | drawerToggle = ActionBarDrawerToggle(
38 | this, drawer_layout, toolbar, R.string.open_drawer, R.string.close_drawer
39 | )
40 | drawer_layout.addDrawerListener(drawerToggle)
41 |
42 | supportActionBar!!.apply {
43 | setDisplayHomeAsUpEnabled(true)
44 | setHomeButtonEnabled(true)
45 | }
46 |
47 | navigation_view.post { navigation_view.setCheckedItem(R.id.item_three) }
48 | navigation_view.setNavigationItemSelectedListener {
49 | navigation_view.setCheckedItem(it.itemId)
50 | false
51 | }
52 | }
53 |
54 | override fun onPostCreate(savedInstanceState: Bundle?) {
55 | super.onPostCreate(savedInstanceState)
56 | // Sync the toggle state after onRestoreInstanceState has occurred.
57 | drawerToggle.syncState()
58 | }
59 |
60 | override fun onConfigurationChanged(newConfig: Configuration) {
61 | super.onConfigurationChanged(newConfig)
62 | drawerToggle.onConfigurationChanged(newConfig)
63 | }
64 |
65 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
66 | return drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/MainAdapter.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.annotation.SuppressLint
19 | import android.view.LayoutInflater
20 | import android.view.View
21 | import android.view.ViewGroup
22 | import androidx.recyclerview.widget.RecyclerView
23 | import com.afollestad.aestheticsample.appcompat.MainAdapter.ViewHolder
24 | import kotlinx.android.synthetic.main.list_item_rv.view.subtitle
25 | import kotlinx.android.synthetic.main.list_item_rv.view.title
26 |
27 | /** @author Aidan Follestad (afollestad) */
28 | internal class MainAdapter : RecyclerView.Adapter() {
29 |
30 | override fun onCreateViewHolder(
31 | parent: ViewGroup,
32 | viewType: Int
33 | ): ViewHolder {
34 | val view = LayoutInflater.from(parent.context)
35 | .inflate(R.layout.list_item_rv, parent, false)
36 | return ViewHolder(view)
37 | }
38 |
39 | @SuppressLint("SetTextI18n")
40 | override fun onBindViewHolder(
41 | holder: ViewHolder,
42 | position: Int
43 | ) {
44 | holder.itemView.title.text = "Item #$position"
45 | holder.itemView.subtitle.setText(R.string.hello_world)
46 | }
47 |
48 | override fun getItemCount(): Int {
49 | return 20
50 | }
51 |
52 | internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
53 | }
54 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/MainPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.content.Context
19 | import androidx.fragment.app.Fragment
20 | import androidx.fragment.app.FragmentManager
21 | import androidx.fragment.app.FragmentStatePagerAdapter
22 |
23 | /** @author Aidan Follestad (afollestad) */
24 | internal class MainPagerAdapter(
25 | private val context: Context,
26 | fm: FragmentManager
27 | ) : FragmentStatePagerAdapter(fm) {
28 |
29 | override fun getItem(position: Int): Fragment {
30 | return if (position == 0) MainFragment() else SecondaryFragment()
31 | }
32 |
33 | override fun getCount(): Int {
34 | return 2
35 | }
36 |
37 | override fun getPageTitle(position: Int): CharSequence? {
38 | return context.getString(if (position == 0) R.string.main else R.string.other)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/RecyclerViewActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.os.Bundle
19 | import androidx.recyclerview.widget.LinearLayoutManager
20 | import com.afollestad.aesthetic.AestheticActivity
21 | import kotlinx.android.synthetic.main.activity_recyclerview.recycler_view
22 | import kotlinx.android.synthetic.main.activity_recyclerview.toolbar
23 |
24 | /** @author Aidan Follestad (afollestad) */
25 | class RecyclerViewActivity : AestheticActivity() {
26 |
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | super.onCreate(savedInstanceState)
29 | setContentView(R.layout.activity_recyclerview)
30 |
31 | toolbar.setNavigationOnClickListener { finish() }
32 | recycler_view.layoutManager = LinearLayoutManager(this)
33 | recycler_view.adapter = MainAdapter()
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/SecondaryFragment.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.content.Intent
19 | import android.os.Bundle
20 | import android.view.LayoutInflater
21 | import android.view.View
22 | import android.view.ViewGroup
23 | import androidx.fragment.app.Fragment
24 | import kotlinx.android.synthetic.main.fragment_secondary.view.drawer_layout
25 | import kotlinx.android.synthetic.main.fragment_secondary.view.recycler_view
26 | import kotlinx.android.synthetic.main.fragment_secondary.view.swipe_refresh
27 |
28 | /** @author Aidan Follestad (afollestad) */
29 | class SecondaryFragment : Fragment() {
30 |
31 | override fun onCreateView(
32 | inflater: LayoutInflater,
33 | container: ViewGroup?,
34 | savedInstanceState: Bundle?
35 | ): View? {
36 | return inflater.inflate(R.layout.fragment_secondary, container, false)
37 | }
38 |
39 | override fun onViewCreated(
40 | view: View,
41 | savedInstanceState: Bundle?
42 | ) {
43 | super.onViewCreated(view, savedInstanceState)
44 |
45 | view.drawer_layout.setOnClickListener {
46 | startActivity(
47 | Intent(activity, DrawerActivity::class.java)
48 | )
49 | }
50 | view.recycler_view.setOnClickListener {
51 | startActivity(
52 | Intent(activity, RecyclerViewActivity::class.java)
53 | )
54 | }
55 | view.swipe_refresh.setOnClickListener {
56 | startActivity(
57 | Intent(activity, SwipeRefreshActivity::class.java)
58 | )
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.os.Bundle
19 | import androidx.preference.PreferenceFragmentCompat
20 | import com.afollestad.aesthetic.AestheticActivity
21 | import kotlinx.android.synthetic.main.activity_settings.toolbar
22 |
23 | class SettingsFragment : PreferenceFragmentCompat() {
24 |
25 | override fun onCreatePreferences(
26 | savedInstanceState: Bundle?,
27 | rootKey: String?
28 | ) = setPreferencesFromResource(R.xml.preferences, rootKey)
29 | }
30 |
31 | class SettingsActivity : AestheticActivity() {
32 |
33 | override fun onCreate(savedInstanceState: Bundle?) {
34 | super.onCreate(savedInstanceState)
35 | setContentView(R.layout.activity_settings)
36 |
37 | toolbar.setOnClickListener { finish() }
38 |
39 | if (savedInstanceState == null) {
40 | supportFragmentManager
41 | .beginTransaction()
42 | .add(R.id.container, SettingsFragment())
43 | .commit()
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/java/com/afollestad/aestheticsample/appcompat/SwipeRefreshActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.afollestad.aestheticsample.appcompat
17 |
18 | import android.os.Bundle
19 | import com.afollestad.aesthetic.AestheticActivity
20 | import io.reactivex.Observable.just
21 | import io.reactivex.disposables.Disposable
22 | import kotlinx.android.synthetic.main.activity_swipe_refresh.swipe_refresh_layout
23 | import kotlinx.android.synthetic.main.activity_swipe_refresh.toolbar
24 | import java.util.concurrent.TimeUnit.SECONDS
25 |
26 | /** @author Aidan Follestad (afollestad) */
27 | class SwipeRefreshActivity : AestheticActivity() {
28 |
29 | private var delayed: Disposable? = null
30 |
31 | override fun onCreate(savedInstanceState: Bundle?) {
32 | super.onCreate(savedInstanceState)
33 | setContentView(R.layout.activity_swipe_refresh)
34 |
35 | toolbar.setNavigationOnClickListener { finish() }
36 | swipe_refresh_layout.setOnRefreshListener {
37 | delayed = just(true)
38 | .delay(2, SECONDS)
39 | .subscribe { swipe_refresh_layout.isRefreshing = false }
40 | }
41 | }
42 |
43 | override fun onPause() {
44 | delayed?.dispose()
45 | super.onPause()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_announcement.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_archive.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_arrow_back.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_attach_money.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_backup.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_book.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_check.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_search.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/drawable/ic_watch.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/activity_demo_appcompat.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
20 |
21 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/activity_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/activity_recyclerview.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
22 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
20 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/activity_swipe_refresh.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
22 |
27 |
28 |
32 |
33 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/fragment_secondary.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
24 |
25 |
32 |
33 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/list_item_rv.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
20 |
21 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/list_item_spinner.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/layout/list_item_spinner_dropdown.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/menu/bottomtabs.xml:
--------------------------------------------------------------------------------
1 |
2 |
25 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/menu/coordinatorlayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
38 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/menu/drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
49 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
40 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-appcompat/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - One
5 | - Two
6 | - Three
7 | - Four
8 | - Five
9 | - Six
10 |
11 |
12 | - 1
13 | - 2
14 | - 3
15 | - 4
16 | - 5
17 | - 6
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #D32F2F
5 | #673AB7
6 | #2196F3
7 | #43A047
8 | #FAFAFA
9 |
10 | #FFC107
11 | #CDDC39
12 | #E91E63
13 | #78909C
14 |
15 | #212121
16 | #424242
17 |
18 | #FAFAFA
19 | #EEEEEE
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 24dp
5 | 16dp
6 | 4dp
7 | 8dp
8 | 12dp
9 |
10 | 24sp
11 | 16sp
12 | 36sp
13 |
14 | 56dp
15 |
16 | 196dp
17 | 272dp
18 |
19 | 6dp
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Aesthetic AC
4 |
5 | Blue
6 | Red
7 | Purple
8 | Green
9 | White
10 |
11 | Hello, world!
12 | Settings
13 |
14 | Text Input Layout
15 | Lorem ipsum dolor sit amet, sed massa wisi, id nisl, sed vitae nec.
16 | Id wisi, sodales interdum auctor. Vestibulum sed.
17 |
18 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sed magna et dolor luctus mollis.
19 | Sed suscipit quam enim, in iaculis turpis finibus quis. Morbi fermentum ante quis magna tempus
20 | suscipit. Sed rhoncus sed felis non elementum. Morbi porttitor molestie mauris, eget maximus
21 | ante sagittis eget. Donec id congue mauris, quis pulvinar erat. Sed cursus est eu erat malesuada
22 | vehicula. Fusce est dui, tempus a leo a, finibus accumsan tellus. Duis vitae sem ullamcorper,
23 | hendrerit odio ac, vestibulum orci. Nunc et dui nec ligula semper congue eget in sapien.
24 | Vestibulum consectetur vel lacus sed hendrerit. Interdum et malesuada fames ac ante ipsum
25 | primis in faucibus. In justo mi, mollis eu leo non, malesuada consequat nisi. Vestibulum
26 | euismod mauris dui, in volutpat est placerat et. In hac habitasse platea dictumst. Cras vitae
27 | suscipit quam. Ut orci enim, laoreet non mi in, convallis pretium quam. Donec lobortis nisi ut
28 | malesuada auctor. Aenean vel porttitor velit. Cras tincidunt, purus ut volutpat mattis, magna
29 | lectus sodales arcu, eget pretium nisi ex et nisi. Vivamus vel euismod nulla. Vivamus eget
30 | metus sit amet lacus tempor faucibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
31 | Fusce sed magna et dolor luctus mollis. Sed suscipit quam enim, in iaculis turpis finibus quis.
32 | Morbi fermentum ante quis magna tempus suscipit. Sed rhoncus sed felis non elementum. Morbi
33 | porttitor molestie mauris, eget maximus ante sagittis eget. Donec id congue mauris, quis
34 | pulvinar erat. Sed cursus est eu erat malesuada vehicula. Fusce est dui, tempus a leo a,
35 | finibus accumsan tellus. Duis vitae sem ullamcorper, hendrerit odio ac, vestibulum orci.
36 | Nunc et dui nec ligula semper congue eget in sapien. Vestibulum consectetur vel lacus sed
37 | hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. In justo mi, mollis
38 | eu leo non, malesuada consequat nisi. Vestibulum euismod mauris dui, in volutpat est placerat
39 | et. In hac habitasse platea dictumst. Cras vitae suscipit quam. Ut orci enim, laoreet non mi
40 | in, convallis pretium quam. Donec lobortis nisi ut malesuada auctor. Aenean vel porttitor velit.
41 | Cras tincidunt, purus ut volutpat mattis, magna lectus sodales arcu, eget pretium nisi ex et nisi.
42 | Vivamus vel euismod nulla. Vivamus eget metus sit amet lacus tempor faucibus.
43 |
44 |
45 | Dark theme
46 | Dark theme on
47 | Dark theme off
48 | Info
49 | Other
50 | Main
51 | Black
52 | Drawer Layout
53 | One
54 | Two
55 | Three
56 | Four
57 | Five
58 | Six
59 | Open Drawer
60 | Close Drawer
61 | Disabled Button
62 | Borderless Button
63 | Search
64 | Search view example…
65 | Recycler View
66 | Show Dialog
67 | Swipe Refresh
68 | Pull down the layout to refresh!
69 | \@resources and #hardcoded colors are not auto themed, only attributes.
70 |
71 |
72 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-appcompat/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
14 |
15 |
20 |
21 |
26 |
27 |
28 |
29 |
31 |
32 |
39 |
40 |
47 |
48 |
49 |
50 |
52 |
53 |
58 |
59 |
66 |
67 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/sample-materialcomponents/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample-materialcomponents/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: '../dependencies.gradle'
2 | apply plugin: 'com.android.application'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'kotlin-kapt'
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion versions.compileSdk
9 | buildToolsVersion versions.buildTools
10 |
11 | defaultConfig {
12 | applicationId "com.afollestad.aestheticsample.materialcomponents"
13 | minSdkVersion versions.minSdk
14 | targetSdkVersion versions.compileSdk
15 | versionCode versions.publishVersionCode
16 | versionName versions.publishVersion
17 | vectorDrawables.useSupportLibrary = true
18 | }
19 |
20 | compileOptions {
21 | kotlinOptions.freeCompilerArgs +=
22 | ['-module-name', "com.afollestad.aestheticsample.materialcomponents"]
23 | }
24 |
25 | packagingOptions {
26 | pickFirst 'META-INF/proguard/androidx-annotations.pro'
27 | }
28 | }
29 |
30 | repositories {
31 | google()
32 | jcenter()
33 | }
34 |
35 | dependencies {
36 | implementation project(':library')
37 |
38 | implementation 'androidx.preference:preference:' + versions.androidx
39 | implementation 'com.google.android.material:material:' + versions.androidx
40 |
41 | implementation 'io.reactivex.rxjava2:rxjava:' + versions.rxJava
42 | implementation 'io.reactivex.rxjava2:rxandroid:' + versions.rxAndroid
43 |
44 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
45 | }
46 |
47 | apply from: '../spotless.gradle'
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_3d_rotation_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_accelerator_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_add_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_dashboard_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_drawer_menu_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/drawable/ic_search_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/layout/activity_demo_materialcomponents.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
24 |
25 |
32 |
33 |
43 |
44 |
45 |
51 |
52 |
53 |
54 |
55 |
56 |
66 |
67 |
74 |
75 |
84 |
85 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/layout/main_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
28 |
29 |
37 |
38 |
46 |
47 |
55 |
56 |
64 |
65 |
73 |
74 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/menu/demo_primary.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample-materialcomponents/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #E0E0E0
5 |
6 | #D32F2F
7 | #673AB7
8 | #2196F3
9 | #43A047
10 | #FAFAFA
11 |
12 | #FFC107
13 | #CDDC39
14 | #E91E63
15 | #78909C
16 |
17 | #212121
18 | #424242
19 |
20 | #FAFAFA
21 | #EEEEEE
22 |
23 |
24 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 128dp
5 |
6 |
7 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Aesthetic MC
4 |
5 | Blue
6 | Red
7 | Purple
8 | Green
9 | White
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample-materialcomponents/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
11 |
17 |
18 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/sample.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afollestad/aesthetic/896215c2905cb1b18467c86e97e2353aacbb19ea/sample.apk
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample-appcompat', ':sample-materialcomponents', ':library'
2 |
--------------------------------------------------------------------------------
/spotless.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.diffplug.gradle.spotless"
2 | spotless {
3 | java {
4 | target "**/*.java"
5 | trimTrailingWhitespace()
6 | removeUnusedImports()
7 | googleJavaFormat()
8 | endWithNewline()
9 | }
10 | kotlin {
11 | target "**/*.kt"
12 | ktlint().userData(['indent_size': '2', 'continuation_indent_size': '2'])
13 | licenseHeaderFile '../spotless.license.kt'
14 | trimTrailingWhitespace()
15 | endWithNewline()
16 | }
17 | }
--------------------------------------------------------------------------------
/spotless.license.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Designed and developed by Aidan Follestad (@afollestad)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
--------------------------------------------------------------------------------
/versionsPlugin.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.github.ben-manes.versions"
2 |
3 | dependencyUpdates.resolutionStrategy {
4 | componentSelection { rules ->
5 | rules.all { ComponentSelection selection ->
6 | boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier ->
7 | selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/
8 | }
9 | if (rejected) {
10 | selection.reject('Not stable')
11 | }
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------