├── .github ├── ci-gradle.properties └── workflows │ └── Check.yaml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README-original.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── androiddevchallenge │ │ │ ├── MainActivity.kt │ │ │ ├── mock │ │ │ └── MockedData.kt │ │ │ ├── model │ │ │ ├── CurrentWeather.kt │ │ │ └── HourlyWeather.kt │ │ │ ├── ui │ │ │ ├── component │ │ │ │ ├── CurrentWeatherCard.kt │ │ │ │ ├── FiveDayListItem.kt │ │ │ │ ├── HourDayListItem.kt │ │ │ │ ├── LottieLoader.kt │ │ │ │ └── WeatherBottomSheet.kt │ │ │ ├── screens │ │ │ │ └── WeatherScreen.kt │ │ │ └── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── Shape.kt │ │ │ │ ├── Theme.kt │ │ │ │ └── Type.kt │ │ │ └── util │ │ │ ├── Constants.kt │ │ │ └── WeatherUtil.kt │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_broken_clouds.png │ │ ├── ic_clear_day.png │ │ ├── ic_cloudy_weather.png │ │ ├── ic_few_clouds.png │ │ ├── ic_mostly_cloudy.png │ │ ├── ic_rainy_weather.png │ │ ├── ic_shower_rain.png │ │ ├── ic_snow_weather.png │ │ ├── ic_storm_weather.png │ │ ├── ic_unknown.png │ │ └── no_city.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_keyboard_arrow_down_24.xml │ │ ├── ic_keyboard_arrow_up_24.xml │ │ └── ic_launcher_background.xml │ │ ├── font │ │ ├── montserrat_bold.ttf │ │ ├── montserrat_extrabold.ttf │ │ ├── montserrat_light.ttf │ │ ├── montserrat_medium.ttf │ │ └── montserrat_semibold.ttf │ │ ├── mipmap-anydpi-v26 │ │ └── ic_launcher.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-mdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.webp │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.webp │ │ ├── raw │ │ ├── broken_clouds.json │ │ ├── clear_day.json │ │ ├── cloudy_weather.json │ │ ├── few_clouds.json │ │ ├── mostly_cloudy.json │ │ ├── rainy_weather.json │ │ ├── shower_rain.json │ │ ├── snow_weather.json │ │ ├── storm_weather.json │ │ └── unknown.json │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── example │ └── androiddevchallenge │ └── ExampleUnitTest.kt ├── build.gradle ├── debug.keystore ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── results ├── screenshot_1.png ├── screenshot_2.png ├── screenshot_3.png ├── screenshot_4.png ├── video.mp4 └── video_a11y.mp4 ├── settings.gradle └── spotless └── copyright.kt /.github/ci-gradle.properties: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Copyright 2020 The Android Open Source Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | org.gradle.daemon=false 19 | org.gradle.parallel=true 20 | org.gradle.jvmargs=-Xmx5120m 21 | org.gradle.workers.max=2 22 | 23 | kotlin.incremental=false 24 | kotlin.compiler.execution.strategy=in-process 25 | -------------------------------------------------------------------------------- /.github/workflows/Check.yaml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 30 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v2 16 | 17 | - name: Copy CI gradle.properties 18 | run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties 19 | 20 | - name: Set up JDK 11 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: 11 24 | 25 | - name: Build project 26 | run: ./gradlew spotlessCheck assembleDebug lintDebug --stacktrace 27 | 28 | - name: Upload build outputs (APKs) 29 | uses: actions/upload-artifact@v2 30 | with: 31 | name: build-outputs 32 | path: app/build/outputs 33 | 34 | - name: Upload build reports 35 | if: always() 36 | uses: actions/upload-artifact@v2 37 | with: 38 | name: build-reports 39 | path: app/build/reports 40 | 41 | test: 42 | needs: build 43 | runs-on: macOS-latest # enables hardware acceleration in the virtual machine 44 | timeout-minutes: 30 45 | strategy: 46 | matrix: 47 | api-level: [23, 26, 29] 48 | 49 | steps: 50 | - name: Checkout 51 | uses: actions/checkout@v2 52 | 53 | - name: Copy CI gradle.properties 54 | run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties 55 | 56 | - name: Set up JDK 11 57 | uses: actions/setup-java@v1 58 | with: 59 | java-version: 11 60 | 61 | - name: Run instrumentation tests 62 | uses: reactivecircus/android-emulator-runner@v2 63 | with: 64 | api-level: ${{ matrix.api-level }} 65 | arch: x86 66 | disable-animations: true 67 | script: ./gradlew connectedCheck --stacktrace 68 | 69 | - name: Upload test reports 70 | if: always() 71 | uses: actions/upload-artifact@v2 72 | with: 73 | name: test-reports 74 | path: app/build/reports 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Mac files 6 | .DS_Store 7 | 8 | # files for the dex VM 9 | *.dex 10 | 11 | # Java class files 12 | *.class 13 | 14 | # generated files 15 | bin/ 16 | gen/ 17 | 18 | # Ignore gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | proguard-project.txt 28 | 29 | # Eclipse files 30 | .project 31 | .classpath 32 | .settings/ 33 | 34 | # Android Studio/IDEA 35 | *.iml 36 | .idea -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README-original.md: -------------------------------------------------------------------------------- 1 | # Template repository 2 | 3 | Template repository for the Jetpack Compose [#AndroidDevChallenge](https://developer.android.com/dev-challenge). 4 | 5 | ## Getting started 6 | Copy this repository by pressing the "Use this template" button in Github. 7 | Clone your repository and open it in the latest [Android Studio (Canary build)](https://developer.android.com/studio/preview). 8 | 9 | ## Submission requirements 10 | - Follow the challenge description on the project website: [developer.android.com/dev-challenge](https://developer.android.com/dev-challenge) 11 | - All UI should be written using Jetpack Compose 12 | - The Github Actions workflow should complete successfully 13 | - Include two screenshots of your submission in the [results](results) folder. The names should be 14 | screenshot_1.png and screenshot_2.png. 15 | - Include a screen record of your submission in the [results](results) folder. The name should be 16 | video.mp4 17 | - Replace the contents of [README.md](README-original.md) with the contents of [README-template.md](README.md) and fill out the template. 18 | 19 | ## Code formatting 20 | The CI uses [Spotless](https://github.com/diffplug/spotless) to check if your code is formatted correctly and contains the right licenses. 21 | Internally, Spotless uses [ktlint](https://github.com/pinterest/ktlint) to check the formatting of your code. 22 | To set up ktlint correctly with Android Studio, follow one of the [listed setup options](https://github.com/pinterest/ktlint#-with-intellij-idea). 23 | 24 | Before committing your code, run `./gradlew app:spotlessApply` to automatically format your code. 25 | 26 | ## License 27 | ``` 28 | Copyright 2020 The Android Open Source Project 29 | 30 | Licensed under the Apache License, Version 2.0 (the "License"); 31 | you may not use this file except in compliance with the License. 32 | You may obtain a copy of the License at 33 | 34 | https://www.apache.org/licenses/LICENSE-2.0 35 | 36 | Unless required by applicable law or agreed to in writing, software 37 | distributed under the License is distributed on an "AS IS" BASIS, 38 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 | See the License for the specific language governing permissions and 40 | limitations under the License. 41 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MiniWeather 2 | 3 | 4 | 5 | ![Workflow result](https://github.com/vsay01/android-dev-challenge-compose-weather/workflows/Check/badge.svg) 6 | 7 | 8 | ## :scroll: Description 9 | MiniWeather is a week 4 challenge project that asked to create a one screen weather app. In this project, I use fake data. 10 | 11 | ## :bulb: Motivation and Context 12 | In this challenge, it focus on: 13 | - Visual beauty 14 | - Novelty of idea 15 | - Code quality 16 | - Overall execution (including accessibility) 17 | 18 | [More detail about the challenge.] 19 | 20 | The main challenge that I faced is write unit test. There are not many resources available. 21 | 22 | ## :camera_flash: Screenshots 23 | 24 | 25 | 26 | Here is demo video: 27 | [demo_video] 28 | 29 | 30 | ## :wheelchair: Accessibility 31 | For accessibility, I tested with google accessibility scanner to make sure no suggestions found. 32 | 33 | 34 | 35 | To make it easier for user to use talkback, I merged the contents wherever possible and provide custom content description. 36 | 37 | [accessibility video] 38 | 39 | ## Testing Compose layout 40 | 41 | I wrote two basic compose layout test, CurrentWeatherCardTest and FiveDayListTest under androidTest package. 42 | 43 | ## Credits 44 | 45 | This app inspired from [Weather App Freebie] concept Designed by [Raman Yv] 46 | 47 | Lottie file are downloaded from [Jochang] 48 | ## License 49 | ``` 50 | Copyright 2020 The Android Open Source Project 51 | 52 | Licensed under the Apache License, Version 2.0 (the "License"); 53 | you may not use this file except in compliance with the License. 54 | You may obtain a copy of the License at 55 | 56 | https://www.apache.org/licenses/LICENSE-2.0 57 | 58 | Unless required by applicable law or agreed to in writing, software 59 | distributed under the License is distributed on an "AS IS" BASIS, 60 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | See the License for the specific language governing permissions and 62 | limitations under the License. 63 | ``` 64 | 65 | [Jochang]: https://lottiefiles.com/user/26177 66 | [accessibility video]: https://user-images.githubusercontent.com/6526127/112253453-bea70a80-8c2c-11eb-8665-e90686dda15e.mp4 67 | [demo_video]: https://user-images.githubusercontent.com/6526127/112253343-8b647b80-8c2c-11eb-9d3c-35c876d410b2.mp4 68 | [More detail about the challenge.]: https://android-developers.googleblog.com/2021/03/android-dev-challenge-4.html 69 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle 3 | build/ 4 | 5 | captures 6 | 7 | /local.properties 8 | 9 | # IntelliJ .idea folder 10 | /.idea 11 | *.iml 12 | 13 | # General 14 | .DS_Store 15 | .externalNativeBuild -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdkVersion 30 8 | 9 | defaultConfig { 10 | applicationId "com.example.androiddevchallenge" 11 | minSdkVersion 23 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | signingConfigs { 20 | // We use a bundled debug keystore, to allow debug builds from CI to be upgradable 21 | debug { 22 | storeFile rootProject.file('debug.keystore') 23 | storePassword 'android' 24 | keyAlias 'androiddebugkey' 25 | keyPassword 'android' 26 | } 27 | } 28 | 29 | buildTypes { 30 | debug { 31 | signingConfig signingConfigs.debug 32 | } 33 | release { 34 | minifyEnabled false 35 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 36 | } 37 | } 38 | 39 | kotlinOptions { 40 | jvmTarget = "1.8" 41 | } 42 | 43 | buildFeatures { 44 | compose true 45 | 46 | // Disable unused AGP features 47 | buildConfig false 48 | aidl false 49 | renderScript false 50 | resValues false 51 | shaders false 52 | } 53 | 54 | composeOptions { 55 | kotlinCompilerExtensionVersion compose_version 56 | } 57 | 58 | packagingOptions { 59 | // Multiple dependency bring these files in. Exclude them to enable 60 | // our test APK to build (has no effect on our AARs) 61 | excludes += "/META-INF/AL2.0" 62 | excludes += "/META-INF/LGPL2.1" 63 | } 64 | } 65 | 66 | dependencies { 67 | implementation 'androidx.core:core-ktx:1.3.2' 68 | implementation 'androidx.appcompat:appcompat:1.3.0-beta01' 69 | implementation 'com.google.android.material:material:1.3.0' 70 | implementation "androidx.activity:activity-compose:1.3.0-alpha04" 71 | implementation "androidx.compose.ui:ui:$compose_version" 72 | implementation "androidx.compose.material:material:$compose_version" 73 | implementation "androidx.compose.material:material-icons-extended:$compose_version" 74 | implementation "androidx.compose.ui:ui-tooling:$compose_version" 75 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0' 76 | 77 | testImplementation 'junit:junit:4.13.2' 78 | 79 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 80 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" 81 | 82 | //coil 83 | implementation "dev.chrisbanes.accompanist:accompanist-coil:0.6.2" 84 | 85 | implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha05" 86 | 87 | implementation 'com.airbnb.android:lottie-compose:1.0.0-alpha07-SNAPSHOT' 88 | 89 | androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_version") 90 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | 16 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/MainActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge 17 | 18 | import android.os.Bundle 19 | import androidx.activity.compose.setContent 20 | import androidx.appcompat.app.AppCompatActivity 21 | import com.example.androiddevchallenge.ui.screens.WeatherScreen 22 | import com.example.androiddevchallenge.ui.theme.MyTheme 23 | 24 | class MainActivity : AppCompatActivity() { 25 | override fun onCreate(savedInstanceState: Bundle?) { 26 | super.onCreate(savedInstanceState) 27 | setContent { 28 | MyTheme { 29 | WeatherScreen() 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/mock/MockedData.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.mock 17 | 18 | import com.example.androiddevchallenge.model.CurrentWeather 19 | import com.example.androiddevchallenge.model.HourlyWeather 20 | import com.example.androiddevchallenge.util.Constants.WEATHER_COLOR 21 | 22 | fun getCurrentWeather() = CurrentWeather( 23 | 1, 2, "clear weather", 800, 58, 12, 10, 14, 4, WEATHER_COLOR[0].toInt(), 24 | listOf( 25 | HourlyWeather("01:00", "clear weather", 800, 8), 26 | HourlyWeather("04:00", "clear weather", 800, 6), 27 | HourlyWeather("07:00", "clear weather", 800, 5), 28 | HourlyWeather("10:00", "cloudy weather", 802, 8), 29 | HourlyWeather("13:00", "clear weather", 800, 12), 30 | HourlyWeather("16:00", "clear weather", 800, 14), 31 | HourlyWeather("19:00", "cloudy weather", 802, 8), 32 | HourlyWeather("22:00", "cloudy weather", 802, 8) 33 | ) 34 | ) 35 | 36 | fun getFiveDayWeather() = listOf( 37 | CurrentWeather( 38 | 2, 3, "rainy weather", 300, 40, 11, 9, 12, 6, WEATHER_COLOR[1].toInt(), 39 | listOf( 40 | HourlyWeather("01:00", "clear weather", 800, 8), 41 | HourlyWeather("04:00", "rainy weather", 300, 6), 42 | HourlyWeather("07:00", "clear weather", 800, 5), 43 | HourlyWeather("10:00", "cloudy weather", 802, 8), 44 | HourlyWeather("13:00", "clear weather", 800, 12), 45 | HourlyWeather("16:00", "rainy weather", 300, 14), 46 | HourlyWeather("19:00", "cloudy weather", 802, 8), 47 | HourlyWeather("22:00", "rainy weather", 300, 11) 48 | ) 49 | ), 50 | CurrentWeather( 51 | 3, 4, "storm weather", 200, 30, 15, 10, 15, 8, WEATHER_COLOR[2].toInt(), 52 | listOf( 53 | HourlyWeather("01:00", "storm weather", 200, 8), 54 | HourlyWeather("04:00", "few cloud weather", 801, 6), 55 | HourlyWeather("07:00", "clear weather", 800, 5), 56 | HourlyWeather("10:00", "cloudy weather", 802, 8), 57 | HourlyWeather("13:00", "storm weather", 800, 12), 58 | HourlyWeather("16:00", "clear weather", 800, 14), 59 | HourlyWeather("19:00", "storm weather", 200, 12), 60 | HourlyWeather("22:00", "storm weather", 200, 11) 61 | ) 62 | ), 63 | CurrentWeather( 64 | 4, 5, "snow weather", 600, 50, 3, 1, 10, 12, WEATHER_COLOR[3].toInt(), 65 | listOf( 66 | HourlyWeather("01:00", "clear weather", 800, 8), 67 | HourlyWeather("04:00", "clear weather", 800, 6), 68 | HourlyWeather("07:00", "snow weather", 600, 5), 69 | HourlyWeather("10:00", "cloudy weather", 802, 8), 70 | HourlyWeather("13:00", "clear weather", 800, 12), 71 | HourlyWeather("16:00", "snow weather", 600, 14), 72 | HourlyWeather("19:00", "snow weather", 600, 12), 73 | HourlyWeather("22:00", "snow weather", 600, 11) 74 | ) 75 | ), 76 | CurrentWeather( 77 | 5, 6, "clear weather", 800, 44, 20, 15, 25, 4, WEATHER_COLOR[0].toInt(), 78 | listOf( 79 | HourlyWeather("01:00", "clear weather", 800, 8), 80 | HourlyWeather("04:00", "clear weather", 800, 6), 81 | HourlyWeather("07:00", "clear weather", 800, 5), 82 | HourlyWeather("10:00", "cloudy weather", 802, 8), 83 | HourlyWeather("13:00", "clear weather", 800, 12), 84 | HourlyWeather("16:00", "clear weather", 800, 14), 85 | HourlyWeather("19:00", "cloudy weather", 802, 8), 86 | HourlyWeather("22:00", "cloudy weather", 802, 8) 87 | ) 88 | ) 89 | ) 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/model/CurrentWeather.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.model 17 | 18 | data class CurrentWeather( 19 | val id: Int, 20 | val day: Int, 21 | val description: String, 22 | val weatherCode: Int, 23 | val humidity: Int, 24 | val temp: Int, 25 | val minTemp: Int, 26 | val maxTemp: Int, 27 | val windSpeed: Int, 28 | val color: Int, 29 | val hourlyWeather: List 30 | ) 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/model/HourlyWeather.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.model 17 | 18 | data class HourlyWeather( 19 | val hour: String, 20 | val description: String, 21 | val weatherCode: Int, 22 | val temp: Int, 23 | ) 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/component/CurrentWeatherCard.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.component 17 | 18 | import androidx.compose.foundation.layout.Arrangement 19 | import androidx.compose.foundation.layout.Column 20 | import androidx.compose.foundation.layout.Row 21 | import androidx.compose.foundation.layout.Spacer 22 | import androidx.compose.foundation.layout.fillMaxWidth 23 | import androidx.compose.foundation.layout.height 24 | import androidx.compose.foundation.layout.padding 25 | import androidx.compose.foundation.layout.size 26 | import androidx.compose.foundation.layout.width 27 | import androidx.compose.material.MaterialTheme 28 | import androidx.compose.material.Surface 29 | import androidx.compose.material.Text 30 | import androidx.compose.runtime.Composable 31 | import androidx.compose.ui.Alignment 32 | import androidx.compose.ui.Modifier 33 | import androidx.compose.ui.graphics.Color 34 | import androidx.compose.ui.res.stringResource 35 | import androidx.compose.ui.semantics.SemanticsProperties 36 | import androidx.compose.ui.semantics.semantics 37 | import androidx.compose.ui.unit.dp 38 | import com.example.androiddevchallenge.R 39 | import com.example.androiddevchallenge.model.CurrentWeather 40 | import com.example.androiddevchallenge.ui.theme.MyTheme 41 | import com.example.androiddevchallenge.ui.theme.shapes 42 | import com.example.androiddevchallenge.util.getWeatherLottie 43 | 44 | @Composable 45 | fun CurrentWeatherCard(currentWeather: CurrentWeather) { 46 | val a11yCurrentCard = String.format( 47 | stringResource(R.string.current_card_a11y), 48 | currentWeather.temp, 49 | currentWeather.description, 50 | currentWeather.humidity, 51 | currentWeather.windSpeed 52 | ) 53 | Surface( 54 | modifier = Modifier 55 | .fillMaxWidth() 56 | .padding(16.dp) 57 | .semantics(mergeDescendants = true) { 58 | this[SemanticsProperties.ContentDescription] = a11yCurrentCard 59 | }, 60 | shape = shapes.medium, 61 | color = Color(currentWeather.color) 62 | ) { 63 | Column( 64 | modifier = Modifier.padding(8.dp), 65 | verticalArrangement = Arrangement.Center, 66 | horizontalAlignment = Alignment.CenterHorizontally 67 | ) { 68 | Text( 69 | text = String.format(stringResource(R.string.temp), currentWeather.temp), 70 | style = MaterialTheme.typography.h1, 71 | color = MyTheme.colors.textColor.value 72 | ) 73 | Spacer(modifier = Modifier.height(16.dp)) 74 | Text( 75 | text = currentWeather.description, 76 | style = MaterialTheme.typography.subtitle1, 77 | color = MyTheme.colors.textColor.value 78 | ) 79 | Spacer(modifier = Modifier.height(16.dp)) 80 | Spacer(modifier = Modifier.height(16.dp)) 81 | Row { 82 | Column( 83 | Modifier.padding(16.dp), 84 | verticalArrangement = Arrangement.Center, 85 | horizontalAlignment = Alignment.CenterHorizontally 86 | ) { 87 | Text( 88 | text = String.format( 89 | stringResource(R.string.humidity), 90 | currentWeather.humidity 91 | ), 92 | style = MaterialTheme.typography.subtitle1, 93 | color = MyTheme.colors.textColor.value 94 | ) 95 | Spacer(modifier = Modifier.height(16.dp)) 96 | Spacer(modifier = Modifier.height(16.dp)) 97 | Text( 98 | text = String.format( 99 | stringResource(R.string.wind_speed), 100 | currentWeather.windSpeed 101 | ), 102 | style = MaterialTheme.typography.subtitle1, 103 | color = MyTheme.colors.textColor.value 104 | ) 105 | } 106 | Spacer(modifier = Modifier.width(24.dp)) 107 | LottieLoader( 108 | modifier = Modifier 109 | .align(Alignment.CenterVertically) 110 | .size(94.dp), 111 | getWeatherLottie(weatherCode = currentWeather.weatherCode) 112 | ) 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/component/FiveDayListItem.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.component 17 | 18 | import androidx.compose.foundation.Image 19 | import androidx.compose.foundation.layout.Arrangement 20 | import androidx.compose.foundation.layout.Column 21 | import androidx.compose.foundation.layout.Row 22 | import androidx.compose.foundation.layout.height 23 | import androidx.compose.foundation.layout.padding 24 | import androidx.compose.foundation.layout.paddingFromBaseline 25 | import androidx.compose.foundation.layout.size 26 | import androidx.compose.foundation.layout.width 27 | import androidx.compose.material.MaterialTheme 28 | import androidx.compose.material.Surface 29 | import androidx.compose.material.Text 30 | import androidx.compose.runtime.Composable 31 | import androidx.compose.ui.Alignment 32 | import androidx.compose.ui.Modifier 33 | import androidx.compose.ui.draw.clip 34 | import androidx.compose.ui.graphics.Color 35 | import androidx.compose.ui.res.painterResource 36 | import androidx.compose.ui.res.stringResource 37 | import androidx.compose.ui.semantics.SemanticsProperties 38 | import androidx.compose.ui.semantics.semantics 39 | import androidx.compose.ui.tooling.preview.Preview 40 | import androidx.compose.ui.unit.dp 41 | import com.example.androiddevchallenge.R 42 | import com.example.androiddevchallenge.mock.getFiveDayWeather 43 | import com.example.androiddevchallenge.model.CurrentWeather 44 | import com.example.androiddevchallenge.ui.theme.MyTheme 45 | import com.example.androiddevchallenge.ui.theme.shapes 46 | import com.example.androiddevchallenge.util.Constants.DAYS_OF_WEEK 47 | import com.example.androiddevchallenge.util.getWeatherLottie 48 | 49 | @Composable 50 | fun FiveDayListItem(weather: CurrentWeather) { 51 | val a11yFiveDayCard = String.format( 52 | stringResource(R.string.five_day_a11y), 53 | DAYS_OF_WEEK[weather.day], 54 | weather.temp, 55 | weather.description 56 | ) 57 | Surface( 58 | shape = shapes.medium, 59 | color = Color(weather.color), 60 | modifier = Modifier 61 | .height(208.dp) 62 | .width(140.dp) 63 | .padding(10.dp) 64 | .semantics(mergeDescendants = true) { 65 | this[SemanticsProperties.ContentDescription] = a11yFiveDayCard 66 | } 67 | ) { 68 | Column( 69 | verticalArrangement = Arrangement.Center, 70 | horizontalAlignment = Alignment.CenterHorizontally 71 | ) { 72 | Text( 73 | text = DAYS_OF_WEEK[weather.day], 74 | style = MaterialTheme.typography.subtitle1, 75 | color = MyTheme.colors.textColor.value, 76 | modifier = Modifier.padding(bottom = 8.dp, top = 8.dp) 77 | ) 78 | LottieLoader( 79 | modifier = Modifier 80 | .size(44.dp) 81 | .padding(bottom = 16.dp, top = 8.dp), 82 | resId = getWeatherLottie(weather.weatherCode) 83 | ) 84 | Text( 85 | text = String.format(stringResource(R.string.temp), weather.temp), 86 | style = MaterialTheme.typography.subtitle1, 87 | color = MyTheme.colors.textColor.value, 88 | modifier = Modifier.padding(bottom = 8.dp) 89 | ) 90 | Row { 91 | Column( 92 | modifier = Modifier.padding(8.dp), 93 | verticalArrangement = Arrangement.Center, 94 | horizontalAlignment = Alignment.CenterHorizontally 95 | ) { 96 | Image( 97 | modifier = Modifier 98 | .clip(MaterialTheme.shapes.small) 99 | .size(34.dp) 100 | .padding(bottom = 8.dp), 101 | painter = painterResource(id = R.drawable.ic_keyboard_arrow_down_24), 102 | contentDescription = String.format( 103 | stringResource(R.string.min_temp_a11y), 104 | weather.minTemp 105 | ) 106 | ) 107 | Text( 108 | text = String.format(stringResource(R.string.temp), weather.minTemp), 109 | style = MaterialTheme.typography.subtitle1, 110 | color = MyTheme.colors.textColor.value, 111 | modifier = Modifier.paddingFromBaseline(24.dp) 112 | ) 113 | } 114 | Column( 115 | modifier = Modifier.padding(8.dp), 116 | verticalArrangement = Arrangement.Center, 117 | horizontalAlignment = Alignment.CenterHorizontally 118 | ) { 119 | Image( 120 | modifier = Modifier 121 | .clip(MaterialTheme.shapes.small) 122 | .size(34.dp) 123 | .padding(bottom = 8.dp), 124 | painter = painterResource(id = R.drawable.ic_keyboard_arrow_up_24), 125 | contentDescription = String.format( 126 | stringResource(R.string.max_temp_a11y), 127 | weather.maxTemp 128 | ) 129 | ) 130 | Text( 131 | text = String.format(stringResource(R.string.temp), weather.maxTemp), 132 | style = MaterialTheme.typography.subtitle1, 133 | color = MyTheme.colors.textColor.value, 134 | modifier = Modifier.paddingFromBaseline(24.dp) 135 | ) 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 143 | @Composable 144 | fun LightPreviewFiveDayListItem() { 145 | MyTheme { 146 | Surface(color = MaterialTheme.colors.secondary) { 147 | FiveDayListItem(getFiveDayWeather()[1]) 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/component/HourDayListItem.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.component 17 | 18 | import androidx.compose.foundation.layout.Arrangement 19 | import androidx.compose.foundation.layout.Column 20 | import androidx.compose.foundation.layout.Row 21 | import androidx.compose.foundation.layout.Spacer 22 | import androidx.compose.foundation.layout.height 23 | import androidx.compose.foundation.layout.padding 24 | import androidx.compose.foundation.layout.size 25 | import androidx.compose.foundation.layout.width 26 | import androidx.compose.material.MaterialTheme 27 | import androidx.compose.material.Surface 28 | import androidx.compose.material.Text 29 | import androidx.compose.runtime.Composable 30 | import androidx.compose.ui.Alignment 31 | import androidx.compose.ui.Modifier 32 | import androidx.compose.ui.res.stringResource 33 | import androidx.compose.ui.semantics.SemanticsProperties 34 | import androidx.compose.ui.semantics.semantics 35 | import androidx.compose.ui.tooling.preview.Preview 36 | import androidx.compose.ui.unit.dp 37 | import com.example.androiddevchallenge.R 38 | import com.example.androiddevchallenge.mock.getCurrentWeather 39 | import com.example.androiddevchallenge.model.HourlyWeather 40 | import com.example.androiddevchallenge.ui.theme.MyTheme 41 | import com.example.androiddevchallenge.util.getWeatherLottie 42 | 43 | @Composable 44 | fun HourDayListItem(hourlyWeather: HourlyWeather) { 45 | val a11yLabel = String.format( 46 | stringResource(R.string.hourly_temp_a11y), 47 | hourlyWeather.hour, 48 | hourlyWeather.description, 49 | hourlyWeather.temp 50 | ) 51 | Row { 52 | Spacer(modifier = Modifier.width(16.dp)) 53 | Column( 54 | verticalArrangement = Arrangement.Center, 55 | horizontalAlignment = Alignment.CenterHorizontally, 56 | modifier = Modifier 57 | .padding(end = 16.dp) 58 | .semantics(mergeDescendants = true) { 59 | this[SemanticsProperties.ContentDescription] = a11yLabel 60 | } 61 | ) { 62 | Text( 63 | text = hourlyWeather.hour, 64 | style = MaterialTheme.typography.h3, 65 | modifier = Modifier.padding(bottom = 8.dp, top = 8.dp) 66 | ) 67 | Spacer(modifier = Modifier.height(8.dp)) 68 | LottieLoader( 69 | modifier = Modifier 70 | .size(44.dp) 71 | .padding(bottom = 8.dp, top = 8.dp), 72 | resId = getWeatherLottie(hourlyWeather.weatherCode) 73 | ) 74 | Spacer(modifier = Modifier.height(16.dp)) 75 | Text( 76 | text = String.format(stringResource(R.string.temp), hourlyWeather.temp), 77 | style = MaterialTheme.typography.h3, 78 | modifier = Modifier.padding(bottom = 8.dp) 79 | ) 80 | } 81 | } 82 | } 83 | 84 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 85 | @Composable 86 | fun LightPreviewHourDayListItem() { 87 | MyTheme { 88 | Surface(color = MaterialTheme.colors.secondary) { 89 | HourDayListItem(getCurrentWeather().hourlyWeather[0]) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/component/LottieLoader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.component 17 | 18 | import androidx.compose.runtime.Composable 19 | import androidx.compose.ui.Modifier 20 | import com.airbnb.lottie.compose.LottieAnimation 21 | import com.airbnb.lottie.compose.LottieAnimationSpec 22 | import com.airbnb.lottie.compose.rememberLottieAnimationState 23 | 24 | @Composable 25 | fun LottieLoader(modifier: Modifier, resId: Int) { 26 | val animationSpec = LottieAnimationSpec.RawRes(resId) 27 | val animationState = rememberLottieAnimationState( 28 | autoPlay = true, 29 | repeatCount = Int.MAX_VALUE 30 | ) 31 | LottieAnimation( 32 | modifier = modifier, 33 | spec = animationSpec, 34 | animationState = animationState 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/component/WeatherBottomSheet.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.component 17 | 18 | import androidx.compose.foundation.Image 19 | import androidx.compose.foundation.layout.Arrangement 20 | import androidx.compose.foundation.layout.Column 21 | import androidx.compose.foundation.layout.Row 22 | import androidx.compose.foundation.layout.Spacer 23 | import androidx.compose.foundation.layout.fillMaxHeight 24 | import androidx.compose.foundation.layout.fillMaxWidth 25 | import androidx.compose.foundation.layout.height 26 | import androidx.compose.foundation.layout.padding 27 | import androidx.compose.foundation.layout.paddingFromBaseline 28 | import androidx.compose.foundation.layout.size 29 | import androidx.compose.foundation.lazy.LazyRow 30 | import androidx.compose.foundation.lazy.items 31 | import androidx.compose.material.MaterialTheme 32 | import androidx.compose.material.Surface 33 | import androidx.compose.material.Text 34 | import androidx.compose.runtime.Composable 35 | import androidx.compose.ui.Alignment 36 | import androidx.compose.ui.Modifier 37 | import androidx.compose.ui.draw.clip 38 | import androidx.compose.ui.graphics.Color 39 | import androidx.compose.ui.res.painterResource 40 | import androidx.compose.ui.res.stringResource 41 | import androidx.compose.ui.semantics.SemanticsProperties 42 | import androidx.compose.ui.semantics.semantics 43 | import androidx.compose.ui.text.style.TextAlign 44 | import androidx.compose.ui.tooling.preview.Preview 45 | import androidx.compose.ui.unit.dp 46 | import com.example.androiddevchallenge.R 47 | import com.example.androiddevchallenge.mock.getCurrentWeather 48 | import com.example.androiddevchallenge.model.CurrentWeather 49 | import com.example.androiddevchallenge.ui.theme.MyTheme 50 | import com.example.androiddevchallenge.ui.theme.shapes 51 | import com.example.androiddevchallenge.util.Constants 52 | import com.example.androiddevchallenge.util.getWeatherLottie 53 | 54 | @Composable 55 | fun WeatherBottomSheetContent(selectedWeather: CurrentWeather) { 56 | val a11yBottomSheetCard = String.format( 57 | stringResource(R.string.five_day_a11y), 58 | Constants.DAYS_OF_WEEK[selectedWeather.day], 59 | selectedWeather.temp, 60 | selectedWeather.description 61 | ) 62 | Surface( 63 | shape = shapes.medium, 64 | color = Color(selectedWeather.color), 65 | modifier = Modifier 66 | .fillMaxHeight(0.85f) 67 | .semantics(mergeDescendants = true) { 68 | this[SemanticsProperties.ContentDescription] = a11yBottomSheetCard 69 | } 70 | ) { 71 | Column( 72 | modifier = Modifier.fillMaxWidth(), 73 | verticalArrangement = Arrangement.Center, 74 | horizontalAlignment = Alignment.CenterHorizontally 75 | ) { 76 | Spacer(modifier = Modifier.height(16.dp)) 77 | Text( 78 | text = Constants.DAYS_OF_WEEK[selectedWeather.day], 79 | style = MaterialTheme.typography.h2, 80 | color = MyTheme.colors.textColor.value 81 | ) 82 | Spacer(modifier = Modifier.height(16.dp)) 83 | LottieLoader( 84 | modifier = Modifier.size(84.dp), 85 | resId = getWeatherLottie(selectedWeather.weatherCode) 86 | ) 87 | Spacer(modifier = Modifier.height(16.dp)) 88 | Text( 89 | text = selectedWeather.description, 90 | style = MaterialTheme.typography.subtitle1, 91 | color = MyTheme.colors.textColor.value 92 | ) 93 | Spacer(modifier = Modifier.height(16.dp)) 94 | Row { 95 | Column( 96 | modifier = Modifier 97 | .padding(start = 16.dp, end = 24.dp) 98 | .weight(1f), 99 | verticalArrangement = Arrangement.Center, 100 | horizontalAlignment = Alignment.CenterHorizontally 101 | ) { 102 | Image( 103 | modifier = Modifier 104 | .clip(MaterialTheme.shapes.small) 105 | .size(34.dp) 106 | .padding(bottom = 8.dp), 107 | painter = painterResource(id = R.drawable.ic_keyboard_arrow_down_24), 108 | contentDescription = String.format( 109 | stringResource(R.string.min_temp_a11y), 110 | selectedWeather.minTemp 111 | ) 112 | ) 113 | Text( 114 | text = String.format( 115 | stringResource(R.string.temp), 116 | selectedWeather.minTemp 117 | ), 118 | style = MaterialTheme.typography.h3, 119 | color = MyTheme.colors.textColor.value, 120 | modifier = Modifier.paddingFromBaseline(24.dp) 121 | ) 122 | } 123 | Text( 124 | text = String.format(stringResource(R.string.temp), selectedWeather.temp), 125 | style = MaterialTheme.typography.h2, 126 | color = MyTheme.colors.textColor.value, 127 | textAlign = TextAlign.Center, 128 | modifier = Modifier 129 | .padding(top = 16.dp, bottom = 8.dp) 130 | .weight(1f) 131 | ) 132 | Column( 133 | modifier = Modifier 134 | .padding(start = 24.dp, end = 16.dp) 135 | .weight(1f), 136 | verticalArrangement = Arrangement.Center, 137 | horizontalAlignment = Alignment.CenterHorizontally 138 | ) { 139 | Image( 140 | modifier = Modifier 141 | .clip(MaterialTheme.shapes.small) 142 | .size(34.dp) 143 | .padding(bottom = 8.dp), 144 | painter = painterResource(id = R.drawable.ic_keyboard_arrow_up_24), 145 | contentDescription = String.format( 146 | stringResource(R.string.max_temp_a11y), 147 | selectedWeather.maxTemp 148 | ) 149 | ) 150 | Text( 151 | text = String.format( 152 | stringResource(R.string.temp), 153 | selectedWeather.maxTemp 154 | ), 155 | style = MaterialTheme.typography.h3, 156 | color = MyTheme.colors.textColor.value, 157 | modifier = Modifier.paddingFromBaseline(24.dp) 158 | ) 159 | } 160 | } 161 | Spacer(modifier = Modifier.height(16.dp)) 162 | Surface( 163 | shape = shapes.large, 164 | color = Color.White, 165 | modifier = Modifier.padding(16.dp) 166 | ) { 167 | LazyRow { 168 | items(selectedWeather.hourlyWeather) { item -> 169 | HourDayListItem(hourlyWeather = item) 170 | } 171 | } 172 | } 173 | } 174 | } 175 | } 176 | 177 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 178 | @Composable 179 | fun PreviewWeatherBottomSheetContentLight() { 180 | MyTheme { 181 | WeatherBottomSheetContent(getCurrentWeather()) 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/screens/WeatherScreen.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.screens 17 | 18 | import androidx.compose.foundation.clickable 19 | import androidx.compose.foundation.layout.Box 20 | import androidx.compose.foundation.layout.Column 21 | import androidx.compose.foundation.layout.fillMaxSize 22 | import androidx.compose.foundation.layout.padding 23 | import androidx.compose.foundation.lazy.LazyRow 24 | import androidx.compose.foundation.lazy.items 25 | import androidx.compose.material.BottomSheetScaffold 26 | import androidx.compose.material.BottomSheetState 27 | import androidx.compose.material.BottomSheetValue 28 | import androidx.compose.material.ExperimentalMaterialApi 29 | import androidx.compose.material.MaterialTheme 30 | import androidx.compose.material.Surface 31 | import androidx.compose.material.Text 32 | import androidx.compose.material.rememberBottomSheetScaffoldState 33 | import androidx.compose.runtime.Composable 34 | import androidx.compose.runtime.mutableStateOf 35 | import androidx.compose.runtime.rememberCoroutineScope 36 | import androidx.compose.ui.Alignment 37 | import androidx.compose.ui.Modifier 38 | import androidx.compose.ui.res.stringResource 39 | import androidx.compose.ui.tooling.preview.Preview 40 | import androidx.compose.ui.unit.dp 41 | import com.example.androiddevchallenge.R 42 | import com.example.androiddevchallenge.mock.getCurrentWeather 43 | import com.example.androiddevchallenge.mock.getFiveDayWeather 44 | import com.example.androiddevchallenge.ui.component.CurrentWeatherCard 45 | import com.example.androiddevchallenge.ui.component.FiveDayListItem 46 | import com.example.androiddevchallenge.ui.component.WeatherBottomSheetContent 47 | import com.example.androiddevchallenge.ui.theme.MyTheme 48 | import kotlinx.coroutines.launch 49 | 50 | @OptIn(ExperimentalMaterialApi::class) 51 | @Composable 52 | fun WeatherScreen() { 53 | val currentWeather = getCurrentWeather() 54 | val selectedWeather = mutableStateOf(currentWeather) 55 | Surface(color = MaterialTheme.colors.background) { 56 | Box { 57 | val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( 58 | bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed) 59 | ) 60 | val coroutineScope = rememberCoroutineScope() 61 | BottomSheetScaffold( 62 | scaffoldState = bottomSheetScaffoldState, 63 | sheetContent = { 64 | WeatherBottomSheetContent(selectedWeather = selectedWeather.value) 65 | }, 66 | sheetPeekHeight = 0.dp 67 | ) { 68 | Column( 69 | modifier = Modifier.fillMaxSize(), 70 | horizontalAlignment = Alignment.CenterHorizontally 71 | ) { 72 | Text( 73 | text = stringResource(R.string.current_weather_label), 74 | style = MaterialTheme.typography.subtitle1, 75 | modifier = Modifier.padding(top = 16.dp) 76 | ) 77 | Box( 78 | Modifier 79 | .padding(start = 8.dp) 80 | .clickable( 81 | onClick = { 82 | coroutineScope.launch { 83 | selectedWeather.value = currentWeather 84 | if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) { 85 | bottomSheetScaffoldState.bottomSheetState.expand() 86 | } else { 87 | bottomSheetScaffoldState.bottomSheetState.collapse() 88 | } 89 | } 90 | } 91 | ) 92 | ) { 93 | CurrentWeatherCard(currentWeather) 94 | } 95 | 96 | Text( 97 | text = stringResource(R.string.next_4_days_label), 98 | style = MaterialTheme.typography.subtitle1, 99 | modifier = Modifier.padding(bottom = 8.dp) 100 | ) 101 | 102 | LazyRow { 103 | items(getFiveDayWeather()) { item -> 104 | Box( 105 | Modifier 106 | .padding(start = 8.dp) 107 | .clickable( 108 | onClick = { 109 | coroutineScope.launch { 110 | selectedWeather.value = item 111 | if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) { 112 | bottomSheetScaffoldState.bottomSheetState.expand() 113 | } else { 114 | bottomSheetScaffoldState.bottomSheetState.collapse() 115 | } 116 | } 117 | } 118 | ) 119 | ) { 120 | FiveDayListItem(weather = item) 121 | } 122 | } 123 | } 124 | } 125 | } 126 | } 127 | } 128 | } 129 | 130 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 131 | @Composable 132 | fun PreviewWeatherScreenLight() { 133 | MyTheme { 134 | WeatherScreen() 135 | } 136 | } 137 | 138 | @Preview("Dark Theme", widthDp = 360, heightDp = 640) 139 | @Composable 140 | fun PreviewWeatherScreenDark() { 141 | MyTheme(darkTheme = true) { 142 | WeatherScreen() 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.theme 17 | 18 | import androidx.compose.ui.graphics.Color 19 | 20 | val teal200 = Color(0xFF03DAC5) 21 | 22 | val blackLight = Color(0xFF161617) 23 | 24 | val graySearchBoxLight = Color(0xFFF2F3F5) 25 | val graySearchBoxDark = Color(0xFF1F1F1F) 26 | 27 | val backgroundLight = Color(0xFFF2F3F5) 28 | val backgroundDark = Color(0xFF0A0A0A) 29 | 30 | val textSecondaryLight = Color(0xFF747577) 31 | val textSecondaryDark = Color(0xFF8B8C8F) 32 | 33 | val transparentGray = Color(0x1AB4B4B4) 34 | val transparentWhite = Color(0x1AFFFFFF) 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.theme 17 | 18 | import androidx.compose.foundation.shape.RoundedCornerShape 19 | import androidx.compose.material.Shapes 20 | import androidx.compose.ui.unit.dp 21 | 22 | val shapes = Shapes( 23 | small = RoundedCornerShape(4.dp), 24 | medium = RoundedCornerShape(16.dp), 25 | large = RoundedCornerShape(38.dp) 26 | ) 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.theme 17 | 18 | import androidx.compose.foundation.isSystemInDarkTheme 19 | import androidx.compose.material.MaterialTheme 20 | import androidx.compose.material.darkColors 21 | import androidx.compose.material.lightColors 22 | import androidx.compose.runtime.Composable 23 | import androidx.compose.runtime.CompositionLocalProvider 24 | import androidx.compose.runtime.Stable 25 | import androidx.compose.runtime.mutableStateOf 26 | import androidx.compose.runtime.remember 27 | import androidx.compose.runtime.staticCompositionLocalOf 28 | import androidx.compose.ui.graphics.Color 29 | 30 | private val DarkColorPalette = darkColors( 31 | primary = blackLight, 32 | primaryVariant = blackLight, 33 | secondary = teal200, 34 | background = backgroundDark, 35 | surface = Color.Black, 36 | onPrimary = Color.White, 37 | onSecondary = Color.White, 38 | onBackground = Color.White, 39 | onSurface = Color.White 40 | ) 41 | 42 | private val LightColorPalette = lightColors( 43 | primary = Color.White, 44 | primaryVariant = Color.White, 45 | secondary = teal200, 46 | background = backgroundLight, 47 | surface = Color.White, 48 | onPrimary = Color.Black, 49 | onSecondary = Color.Black, 50 | onBackground = Color.Black, 51 | onSurface = Color.Black 52 | ) 53 | 54 | private val MyLightColorPalette = MyColors( 55 | transparentBackground = transparentGray, 56 | textColor = Color.White, 57 | textPrimaryColor = Color.Black, 58 | textSecondaryColor = textSecondaryLight, 59 | searchBoxColor = graySearchBoxLight, 60 | isDark = false 61 | ) 62 | 63 | private val MyDarkColorPalette = MyColors( 64 | transparentBackground = transparentWhite, 65 | textColor = Color.White, 66 | textPrimaryColor = Color.White, 67 | textSecondaryColor = textSecondaryDark, 68 | searchBoxColor = graySearchBoxDark, 69 | isDark = true 70 | ) 71 | 72 | @Composable 73 | fun MyTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { 74 | val (colors, customColors) = if (darkTheme) DarkColorPalette to MyDarkColorPalette else LightColorPalette to MyLightColorPalette 75 | ProvideMyColors(customColors) { 76 | MaterialTheme( 77 | colors = colors, 78 | typography = typography, 79 | content = content 80 | ) 81 | } 82 | } 83 | 84 | object MyTheme { 85 | val colors: MyColors 86 | @Composable 87 | get() = LocalMyColors.current 88 | } 89 | 90 | @Composable 91 | fun ProvideMyColors( 92 | colors: MyColors, 93 | content: @Composable () -> Unit 94 | ) { 95 | val colorPalette = remember { colors } 96 | colorPalette.update(colors) 97 | CompositionLocalProvider(LocalMyColors provides colorPalette, content = content) 98 | } 99 | 100 | private val LocalMyColors = staticCompositionLocalOf { 101 | error("No LocalMyColorsPalette provided") 102 | } 103 | 104 | @Stable 105 | class MyColors( 106 | transparentBackground: Color, 107 | textColor: Color, 108 | textPrimaryColor: Color, 109 | textSecondaryColor: Color, 110 | searchBoxColor: Color, 111 | isDark: Boolean 112 | ) { 113 | var transparentBackground = mutableStateOf(transparentBackground) 114 | private set 115 | var textColor = mutableStateOf(textColor) 116 | private set 117 | var textPrimaryColor = mutableStateOf(textPrimaryColor) 118 | private set 119 | var textSecondaryColor = mutableStateOf(textSecondaryColor) 120 | private set 121 | var searchBoxColor = mutableStateOf(searchBoxColor) 122 | private set 123 | var isDark = mutableStateOf(isDark) 124 | private set 125 | 126 | fun update(other: MyColors) { 127 | transparentBackground = other.transparentBackground 128 | textColor = other.textColor 129 | textPrimaryColor = other.textPrimaryColor 130 | textSecondaryColor = other.textSecondaryColor 131 | searchBoxColor = other.searchBoxColor 132 | isDark = other.isDark 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.ui.theme 17 | 18 | import androidx.compose.material.Typography 19 | import androidx.compose.ui.text.TextStyle 20 | import androidx.compose.ui.text.font.Font 21 | import androidx.compose.ui.text.font.FontFamily 22 | import androidx.compose.ui.text.font.FontWeight 23 | import androidx.compose.ui.unit.sp 24 | import com.example.androiddevchallenge.R 25 | 26 | // Set of Material typography styles to start with 27 | val typography = Typography( 28 | h1 = TextStyle( 29 | fontFamily = FontFamily(Font(R.font.montserrat_extrabold)), 30 | fontWeight = FontWeight.ExtraBold, 31 | fontSize = 40.sp, 32 | letterSpacing = 1.25.sp 33 | ), 34 | h2 = TextStyle( 35 | fontFamily = FontFamily(Font(R.font.montserrat_extrabold)), 36 | fontWeight = FontWeight.ExtraBold, 37 | fontSize = 30.sp 38 | ), 39 | h3 = TextStyle( 40 | fontFamily = FontFamily(Font(R.font.montserrat_semibold)), 41 | fontWeight = FontWeight.SemiBold, 42 | fontSize = 18.sp 43 | ), 44 | subtitle1 = TextStyle( 45 | fontFamily = FontFamily(Font(R.font.montserrat_medium)), 46 | fontWeight = FontWeight.Medium, 47 | fontSize = 15.sp 48 | ), 49 | body1 = TextStyle( 50 | fontFamily = FontFamily(Font(R.font.montserrat_light)), 51 | fontWeight = FontWeight.Light, 52 | fontSize = 13.sp 53 | ), 54 | button = TextStyle( 55 | fontFamily = FontFamily(Font(R.font.montserrat_bold)), 56 | fontWeight = FontWeight.Bold, 57 | fontSize = 13.sp, 58 | letterSpacing = 1.25.sp 59 | ) 60 | ) 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/util/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.util 17 | 18 | object Constants { 19 | val DAYS_OF_WEEK = arrayOf( 20 | "Sunday", 21 | "Monday", 22 | "Tuesday", 23 | "Wednesday", 24 | "Thursday", 25 | "Friday", 26 | "Saturday" 27 | ) 28 | 29 | val WEATHER_COLOR = arrayOf( 30 | 0xFF5f5be7, 31 | 0xFF1f6841, 32 | 0xFFeb378e, 33 | 0xFFa96f0a 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/util/WeatherUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 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 | * https://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.example.androiddevchallenge.util 17 | 18 | import com.example.androiddevchallenge.R 19 | 20 | fun getWeatherIcon(weatherCode: Int) = when { 21 | weatherCode / 100 == 2 -> { 22 | R.drawable.ic_storm_weather 23 | } 24 | weatherCode / 100 == 3 -> { 25 | R.drawable.ic_rainy_weather 26 | } 27 | weatherCode / 100 == 6 -> { 28 | R.drawable.ic_snow_weather 29 | } 30 | weatherCode / 100 == 7 -> { 31 | R.drawable.ic_unknown 32 | } 33 | weatherCode == 800 -> { 34 | R.drawable.ic_clear_day 35 | } 36 | weatherCode == 801 -> { 37 | R.drawable.ic_few_clouds 38 | } 39 | weatherCode == 803 -> { 40 | R.drawable.ic_broken_clouds 41 | } 42 | weatherCode == 802 -> { 43 | R.drawable.ic_cloudy_weather 44 | } 45 | else -> R.drawable.ic_unknown 46 | } 47 | 48 | fun getWeatherLottie(weatherCode: Int) = when { 49 | weatherCode / 100 == 2 -> { 50 | R.raw.storm_weather 51 | } 52 | weatherCode / 100 == 3 -> { 53 | R.raw.rainy_weather 54 | } 55 | weatherCode / 100 == 6 -> { 56 | R.raw.snow_weather 57 | } 58 | weatherCode / 100 == 7 -> { 59 | R.drawable.ic_unknown 60 | } 61 | weatherCode == 800 -> { 62 | R.raw.clear_day 63 | } 64 | weatherCode == 801 -> { 65 | R.raw.few_clouds 66 | } 67 | weatherCode == 803 -> { 68 | R.raw.broken_clouds 69 | } 70 | weatherCode == 802 -> { 71 | R.raw.cloudy_weather 72 | } 73 | else -> R.drawable.ic_unknown 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_broken_clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_broken_clouds.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_clear_day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_clear_day.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_cloudy_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_cloudy_weather.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_few_clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_few_clouds.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_mostly_cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_mostly_cloudy.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_rainy_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_rainy_weather.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_shower_rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_shower_rain.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_snow_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_snow_weather.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_storm_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_storm_weather.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/ic_unknown.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/no_city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/drawable-hdpi/no_city.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 11 | 17 | 18 | 19 | 25 | 28 | 31 | 32 | 33 | 34 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_down_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_up_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 17 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 175 | 180 | 181 | -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/font/montserrat_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat_extrabold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/font/montserrat_extrabold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/font/montserrat_light.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/font/montserrat_medium.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/montserrat_semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/font/montserrat_semibold.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsay01/android-dev-challenge-compose-weather/cfa67f85a3bd37ed33364a2b030a0b9e26a29182/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/raw/clear_day.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": "5.1.1", 3 | "fr": 60, 4 | "ip": 0, 5 | "op": 180, 6 | "w": 256, 7 | "h": 256, 8 | "nm": "Sunny", 9 | "ddd": 0, 10 | "assets": [], 11 | "layers": [ 12 | { 13 | "ddd": 0, 14 | "ind": 1, 15 | "ty": 4, 16 | "nm": "Oval ", 17 | "sr": 1, 18 | "ks": { 19 | "o": { 20 | "a": 0, 21 | "k": 100, 22 | "ix": 11 23 | }, 24 | "r": { 25 | "a": 0, 26 | "k": 0, 27 | "ix": 10 28 | }, 29 | "p": { 30 | "a": 0, 31 | "k": [ 32 | 127.43, 33 | 127.43, 34 | 0 35 | ], 36 | "ix": 2 37 | }, 38 | "a": { 39 | "a": 0, 40 | "k": [ 41 | 0, 42 | 0, 43 | 0 44 | ], 45 | "ix": 1 46 | }, 47 | "s": { 48 | "a": 1, 49 | "k": [ 50 | { 51 | "i": { 52 | "x": [ 53 | 0.833, 54 | 0.833, 55 | 0.833 56 | ], 57 | "y": [ 58 | 0.833, 59 | 0.833, 60 | -0.294 61 | ] 62 | }, 63 | "o": { 64 | "x": [ 65 | 0.333, 66 | 0.333, 67 | 0.333 68 | ], 69 | "y": [ 70 | 0, 71 | 0, 72 | 0 73 | ] 74 | }, 75 | "n": [ 76 | "0p833_0p833_0p333_0", 77 | "0p833_0p833_0p333_0", 78 | "0p833_-0p294_0p333_0" 79 | ], 80 | "t": 0, 81 | "s": [ 82 | 100, 83 | 100, 84 | 100 85 | ], 86 | "e": [ 87 | 103, 88 | 103, 89 | 100 90 | ] 91 | }, 92 | { 93 | "i": { 94 | "x": [ 95 | 0.833, 96 | 0.833, 97 | 0.833 98 | ], 99 | "y": [ 100 | 0.833, 101 | 0.833, 102 | 1.985 103 | ] 104 | }, 105 | "o": { 106 | "x": [ 107 | 0.333, 108 | 0.333, 109 | 0.333 110 | ], 111 | "y": [ 112 | 0, 113 | 0, 114 | 0 115 | ] 116 | }, 117 | "n": [ 118 | "0p833_0p833_0p333_0", 119 | "0p833_0p833_0p333_0", 120 | "0p833_1p985_0p333_0" 121 | ], 122 | "t": 35, 123 | "s": [ 124 | 103, 125 | 103, 126 | 100 127 | ], 128 | "e": [ 129 | 100, 130 | 100, 131 | 100 132 | ] 133 | }, 134 | { 135 | "i": { 136 | "x": [ 137 | 0.833, 138 | 0.833, 139 | 0.833 140 | ], 141 | "y": [ 142 | 0.833, 143 | 0.833, 144 | 15.47 145 | ] 146 | }, 147 | "o": { 148 | "x": [ 149 | 0.333, 150 | 0.333, 151 | 0.333 152 | ], 153 | "y": [ 154 | 0, 155 | 0, 156 | 0 157 | ] 158 | }, 159 | "n": [ 160 | "0p833_0p833_0p333_0", 161 | "0p833_0p833_0p333_0", 162 | "0p833_15p47_0p333_0" 163 | ], 164 | "t": 80, 165 | "s": [ 166 | 100, 167 | 100, 168 | 100 169 | ], 170 | "e": [ 171 | 103, 172 | 103, 173 | 100 174 | ] 175 | }, 176 | { 177 | "i": { 178 | "x": [ 179 | 0.833, 180 | 0.833, 181 | 0.833 182 | ], 183 | "y": [ 184 | 0.833, 185 | 0.833, 186 | -13.47 187 | ] 188 | }, 189 | "o": { 190 | "x": [ 191 | 0.333, 192 | 0.333, 193 | 0.333 194 | ], 195 | "y": [ 196 | 0, 197 | 0, 198 | 0 199 | ] 200 | }, 201 | "n": [ 202 | "0p833_0p833_0p333_0", 203 | "0p833_0p833_0p333_0", 204 | "0p833_-13p47_0p333_0" 205 | ], 206 | "t": 125, 207 | "s": [ 208 | 103, 209 | 103, 210 | 100 211 | ], 212 | "e": [ 213 | 100, 214 | 100, 215 | 100 216 | ] 217 | }, 218 | { 219 | "t": 180 220 | } 221 | ], 222 | "ix": 6 223 | } 224 | }, 225 | "ao": 0, 226 | "shapes": [ 227 | { 228 | "ty": "gr", 229 | "it": [ 230 | { 231 | "d": 1, 232 | "ty": "el", 233 | "s": { 234 | "a": 0, 235 | "k": [ 236 | 153.6, 237 | 153.6 238 | ], 239 | "ix": 2 240 | }, 241 | "p": { 242 | "a": 0, 243 | "k": [ 244 | 0, 245 | 0 246 | ], 247 | "ix": 3 248 | }, 249 | "nm": "Ellipse Path 1", 250 | "mn": "ADBE Vector Shape - Ellipse", 251 | "hd": false 252 | }, 253 | { 254 | "ty": "fl", 255 | "c": { 256 | "a": 0, 257 | "k": [ 258 | 1, 259 | 0.788235008717, 260 | 0.188234999776, 261 | 1 262 | ], 263 | "ix": 4 264 | }, 265 | "o": { 266 | "a": 0, 267 | "k": 100, 268 | "ix": 5 269 | }, 270 | "r": 1, 271 | "nm": "Fill 1", 272 | "mn": "ADBE Vector Graphic - Fill", 273 | "hd": false 274 | }, 275 | { 276 | "ty": "tr", 277 | "p": { 278 | "a": 0, 279 | "k": [ 280 | 0, 281 | 0 282 | ], 283 | "ix": 2 284 | }, 285 | "a": { 286 | "a": 0, 287 | "k": [ 288 | 0, 289 | 0 290 | ], 291 | "ix": 1 292 | }, 293 | "s": { 294 | "a": 0, 295 | "k": [ 296 | 100, 297 | 100 298 | ], 299 | "ix": 3 300 | }, 301 | "r": { 302 | "a": 0, 303 | "k": 0, 304 | "ix": 6 305 | }, 306 | "o": { 307 | "a": 0, 308 | "k": 100, 309 | "ix": 7 310 | }, 311 | "sk": { 312 | "a": 0, 313 | "k": 0, 314 | "ix": 4 315 | }, 316 | "sa": { 317 | "a": 0, 318 | "k": 0, 319 | "ix": 5 320 | }, 321 | "nm": "Transform" 322 | } 323 | ], 324 | "nm": "Oval ", 325 | "np": 2, 326 | "cix": 2, 327 | "ix": 1, 328 | "mn": "ADBE Vector Group", 329 | "hd": false 330 | } 331 | ], 332 | "ip": 0, 333 | "op": 180, 334 | "st": 0, 335 | "bm": 0 336 | }, 337 | { 338 | "ddd": 0, 339 | "ind": 2, 340 | "ty": 4, 341 | "nm": "Oval", 342 | "sr": 1, 343 | "ks": { 344 | "o": { 345 | "a": 0, 346 | "k": 100, 347 | "ix": 11 348 | }, 349 | "r": { 350 | "a": 0, 351 | "k": 0, 352 | "ix": 10 353 | }, 354 | "p": { 355 | "a": 0, 356 | "k": [ 357 | 127.435, 358 | 127.435, 359 | 0 360 | ], 361 | "ix": 2 362 | }, 363 | "a": { 364 | "a": 0, 365 | "k": [ 366 | 0, 367 | 0, 368 | 0 369 | ], 370 | "ix": 1 371 | }, 372 | "s": { 373 | "a": 1, 374 | "k": [ 375 | { 376 | "i": { 377 | "x": [ 378 | 0.833, 379 | 0.833, 380 | 0.833 381 | ], 382 | "y": [ 383 | 0.833, 384 | 0.833, 385 | 0.833 386 | ] 387 | }, 388 | "o": { 389 | "x": [ 390 | 0.167, 391 | 0.167, 392 | 0.167 393 | ], 394 | "y": [ 395 | 0.167, 396 | 0.167, 397 | 0.167 398 | ] 399 | }, 400 | "n": [ 401 | "0p833_0p833_0p167_0p167", 402 | "0p833_0p833_0p167_0p167", 403 | "0p833_0p833_0p167_0p167" 404 | ], 405 | "t": 0, 406 | "s": [ 407 | 98, 408 | 98, 409 | 100 410 | ], 411 | "e": [ 412 | 101, 413 | 101, 414 | 100 415 | ] 416 | }, 417 | { 418 | "i": { 419 | "x": [ 420 | 0.833, 421 | 0.833, 422 | 0.833 423 | ], 424 | "y": [ 425 | 0.833, 426 | 0.833, 427 | 2.005 428 | ] 429 | }, 430 | "o": { 431 | "x": [ 432 | 0.333, 433 | 0.333, 434 | 0.333 435 | ], 436 | "y": [ 437 | 0, 438 | 0, 439 | 0 440 | ] 441 | }, 442 | "n": [ 443 | "0p833_0p833_0p333_0", 444 | "0p833_0p833_0p333_0", 445 | "0p833_2p005_0p333_0" 446 | ], 447 | "t": 40, 448 | "s": [ 449 | 101, 450 | 101, 451 | 100 452 | ], 453 | "e": [ 454 | 98, 455 | 98, 456 | 100 457 | ] 458 | }, 459 | { 460 | "i": { 461 | "x": [ 462 | 0.833, 463 | 0.833, 464 | 0.833 465 | ], 466 | "y": [ 467 | 0.833, 468 | 0.833, 469 | -0.005 470 | ] 471 | }, 472 | "o": { 473 | "x": [ 474 | 0.333, 475 | 0.333, 476 | 0.333 477 | ], 478 | "y": [ 479 | 0, 480 | 0, 481 | 0 482 | ] 483 | }, 484 | "n": [ 485 | "0p833_0p833_0p333_0", 486 | "0p833_0p833_0p333_0", 487 | "0p833_-0p005_0p333_0" 488 | ], 489 | "t": 85, 490 | "s": [ 491 | 98, 492 | 98, 493 | 100 494 | ], 495 | "e": [ 496 | 101, 497 | 101, 498 | 100 499 | ] 500 | }, 501 | { 502 | "i": { 503 | "x": [ 504 | 0.833, 505 | 0.833, 506 | 0.833 507 | ], 508 | "y": [ 509 | 1, 510 | 1, 511 | 1 512 | ] 513 | }, 514 | "o": { 515 | "x": [ 516 | 0.333, 517 | 0.333, 518 | 0.333 519 | ], 520 | "y": [ 521 | 0, 522 | 0, 523 | 0 524 | ] 525 | }, 526 | "n": [ 527 | "0p833_1_0p333_0", 528 | "0p833_1_0p333_0", 529 | "0p833_1_0p333_0" 530 | ], 531 | "t": 130, 532 | "s": [ 533 | 101, 534 | 101, 535 | 100 536 | ], 537 | "e": [ 538 | 98, 539 | 98, 540 | 100 541 | ] 542 | }, 543 | { 544 | "t": 180 545 | } 546 | ], 547 | "ix": 6 548 | } 549 | }, 550 | "ao": 0, 551 | "shapes": [ 552 | { 553 | "ty": "gr", 554 | "it": [ 555 | { 556 | "d": 1, 557 | "ty": "el", 558 | "s": { 559 | "a": 0, 560 | "k": [ 561 | 180.91, 562 | 180.91 563 | ], 564 | "ix": 2 565 | }, 566 | "p": { 567 | "a": 0, 568 | "k": [ 569 | 0, 570 | 0 571 | ], 572 | "ix": 3 573 | }, 574 | "nm": "Ellipse Path 1", 575 | "mn": "ADBE Vector Shape - Ellipse", 576 | "hd": false 577 | }, 578 | { 579 | "ty": "st", 580 | "c": { 581 | "a": 0, 582 | "k": [ 583 | 1, 584 | 0.860368013382, 585 | 0.464744985104, 586 | 1 587 | ], 588 | "ix": 3 589 | }, 590 | "o": { 591 | "a": 0, 592 | "k": 100, 593 | "ix": 4 594 | }, 595 | "w": { 596 | "a": 0, 597 | "k": 8.533, 598 | "ix": 5 599 | }, 600 | "lc": 1, 601 | "lj": 1, 602 | "ml": 4, 603 | "nm": "Stroke 1", 604 | "mn": "ADBE Vector Graphic - Stroke", 605 | "hd": false 606 | }, 607 | { 608 | "ty": "tr", 609 | "p": { 610 | "a": 0, 611 | "k": [ 612 | 0, 613 | 0 614 | ], 615 | "ix": 2 616 | }, 617 | "a": { 618 | "a": 0, 619 | "k": [ 620 | 0, 621 | 0 622 | ], 623 | "ix": 1 624 | }, 625 | "s": { 626 | "a": 0, 627 | "k": [ 628 | 100, 629 | 100 630 | ], 631 | "ix": 3 632 | }, 633 | "r": { 634 | "a": 0, 635 | "k": 0, 636 | "ix": 6 637 | }, 638 | "o": { 639 | "a": 0, 640 | "k": 100, 641 | "ix": 7 642 | }, 643 | "sk": { 644 | "a": 0, 645 | "k": 0, 646 | "ix": 4 647 | }, 648 | "sa": { 649 | "a": 0, 650 | "k": 0, 651 | "ix": 5 652 | }, 653 | "nm": "Transform" 654 | } 655 | ], 656 | "nm": "Oval", 657 | "np": 2, 658 | "cix": 2, 659 | "ix": 1, 660 | "mn": "ADBE Vector Group", 661 | "hd": false 662 | } 663 | ], 664 | "ip": 0, 665 | "op": 180, 666 | "st": 0, 667 | "bm": 0 668 | }, 669 | { 670 | "ddd": 0, 671 | "ind": 3, 672 | "ty": 4, 673 | "nm": "Oval", 674 | "sr": 1, 675 | "ks": { 676 | "o": { 677 | "a": 0, 678 | "k": 100, 679 | "ix": 11 680 | }, 681 | "r": { 682 | "a": 0, 683 | "k": 0, 684 | "ix": 10 685 | }, 686 | "p": { 687 | "a": 0, 688 | "k": [ 689 | 128, 690 | 128, 691 | 0 692 | ], 693 | "ix": 2 694 | }, 695 | "a": { 696 | "a": 0, 697 | "k": [ 698 | 0, 699 | 0, 700 | 0 701 | ], 702 | "ix": 1 703 | }, 704 | "s": { 705 | "a": 1, 706 | "k": [ 707 | { 708 | "i": { 709 | "x": [ 710 | 0.833, 711 | 0.833, 712 | 0.833 713 | ], 714 | "y": [ 715 | 0.833, 716 | 0.833, 717 | 0.015 718 | ] 719 | }, 720 | "o": { 721 | "x": [ 722 | 0.333, 723 | 0.333, 724 | 0.333 725 | ], 726 | "y": [ 727 | 0, 728 | 0, 729 | 0 730 | ] 731 | }, 732 | "n": [ 733 | "0p833_0p833_0p333_0", 734 | "0p833_0p833_0p333_0", 735 | "0p833_0p015_0p333_0" 736 | ], 737 | "t": 0, 738 | "s": [ 739 | 100, 740 | 100, 741 | 100 742 | ], 743 | "e": [ 744 | 103, 745 | 103, 746 | 100 747 | ] 748 | }, 749 | { 750 | "i": { 751 | "x": [ 752 | 0.833, 753 | 0.833, 754 | 0.833 755 | ], 756 | "y": [ 757 | 0.833, 758 | 0.833, 759 | 1.985 760 | ] 761 | }, 762 | "o": { 763 | "x": [ 764 | 0.333, 765 | 0.333, 766 | 0.333 767 | ], 768 | "y": [ 769 | 0, 770 | 0, 771 | 0 772 | ] 773 | }, 774 | "n": [ 775 | "0p833_0p833_0p333_0", 776 | "0p833_0p833_0p333_0", 777 | "0p833_1p985_0p333_0" 778 | ], 779 | "t": 45, 780 | "s": [ 781 | 103, 782 | 103, 783 | 100 784 | ], 785 | "e": [ 786 | 100, 787 | 100, 788 | 100 789 | ] 790 | }, 791 | { 792 | "i": { 793 | "x": [ 794 | 0.833, 795 | 0.833, 796 | 0.833 797 | ], 798 | "y": [ 799 | 0.833, 800 | 0.833, 801 | 0.015 802 | ] 803 | }, 804 | "o": { 805 | "x": [ 806 | 0.333, 807 | 0.333, 808 | 0.333 809 | ], 810 | "y": [ 811 | 0, 812 | 0, 813 | 0 814 | ] 815 | }, 816 | "n": [ 817 | "0p833_0p833_0p333_0", 818 | "0p833_0p833_0p333_0", 819 | "0p833_0p015_0p333_0" 820 | ], 821 | "t": 90, 822 | "s": [ 823 | 100, 824 | 100, 825 | 100 826 | ], 827 | "e": [ 828 | 103, 829 | 103, 830 | 100 831 | ] 832 | }, 833 | { 834 | "i": { 835 | "x": [ 836 | 0.833, 837 | 0.833, 838 | 0.833 839 | ], 840 | "y": [ 841 | 0.833, 842 | 0.833, 843 | 1.985 844 | ] 845 | }, 846 | "o": { 847 | "x": [ 848 | 0.333, 849 | 0.333, 850 | 0.333 851 | ], 852 | "y": [ 853 | 0, 854 | 0, 855 | 0 856 | ] 857 | }, 858 | "n": [ 859 | "0p833_0p833_0p333_0", 860 | "0p833_0p833_0p333_0", 861 | "0p833_1p985_0p333_0" 862 | ], 863 | "t": 135, 864 | "s": [ 865 | 103, 866 | 103, 867 | 100 868 | ], 869 | "e": [ 870 | 100, 871 | 100, 872 | 100 873 | ] 874 | }, 875 | { 876 | "t": 180 877 | } 878 | ], 879 | "ix": 6 880 | } 881 | }, 882 | "ao": 0, 883 | "shapes": [ 884 | { 885 | "ty": "gr", 886 | "it": [ 887 | { 888 | "d": 1, 889 | "ty": "el", 890 | "s": { 891 | "a": 0, 892 | "k": [ 893 | 204.8, 894 | 204.8 895 | ], 896 | "ix": 2 897 | }, 898 | "p": { 899 | "a": 0, 900 | "k": [ 901 | 0, 902 | 0 903 | ], 904 | "ix": 3 905 | }, 906 | "nm": "Ellipse Path 1", 907 | "mn": "ADBE Vector Shape - Ellipse", 908 | "hd": false 909 | }, 910 | { 911 | "ty": "st", 912 | "c": { 913 | "a": 0, 914 | "k": [ 915 | 1, 916 | 0.961977005005, 917 | 0.856356978416, 918 | 1 919 | ], 920 | "ix": 3 921 | }, 922 | "o": { 923 | "a": 0, 924 | "k": 100, 925 | "ix": 4 926 | }, 927 | "w": { 928 | "a": 0, 929 | "k": 4.571, 930 | "ix": 5 931 | }, 932 | "lc": 1, 933 | "lj": 1, 934 | "ml": 4, 935 | "nm": "Stroke 1", 936 | "mn": "ADBE Vector Graphic - Stroke", 937 | "hd": false 938 | }, 939 | { 940 | "ty": "tr", 941 | "p": { 942 | "a": 0, 943 | "k": [ 944 | 0, 945 | 0 946 | ], 947 | "ix": 2 948 | }, 949 | "a": { 950 | "a": 0, 951 | "k": [ 952 | 0, 953 | 0 954 | ], 955 | "ix": 1 956 | }, 957 | "s": { 958 | "a": 0, 959 | "k": [ 960 | 100, 961 | 100 962 | ], 963 | "ix": 3 964 | }, 965 | "r": { 966 | "a": 0, 967 | "k": 0, 968 | "ix": 6 969 | }, 970 | "o": { 971 | "a": 0, 972 | "k": 100, 973 | "ix": 7 974 | }, 975 | "sk": { 976 | "a": 0, 977 | "k": 0, 978 | "ix": 4 979 | }, 980 | "sa": { 981 | "a": 0, 982 | "k": 0, 983 | "ix": 5 984 | }, 985 | "nm": "Transform" 986 | } 987 | ], 988 | "nm": "Oval", 989 | "np": 2, 990 | "cix": 2, 991 | "ix": 1, 992 | "mn": "ADBE Vector Group", 993 | "hd": false 994 | } 995 | ], 996 | "ip": 0, 997 | "op": 180, 998 | "st": 0, 999 | "bm": 0 1000 | }, 1001 | { 1002 | "ddd": 0, 1003 | "ind": 4, 1004 | "ty": 4, 1005 | "nm": "bond", 1006 | "sr": 1, 1007 | "ks": { 1008 | "o": { 1009 | "a": 0, 1010 | "k": 100, 1011 | "ix": 11 1012 | }, 1013 | "r": { 1014 | "a": 0, 1015 | "k": 0, 1016 | "ix": 10 1017 | }, 1018 | "p": { 1019 | "a": 0, 1020 | "k": [ 1021 | 128, 1022 | 128, 1023 | 0 1024 | ], 1025 | "ix": 2 1026 | }, 1027 | "a": { 1028 | "a": 0, 1029 | "k": [ 1030 | 0, 1031 | 0, 1032 | 0 1033 | ], 1034 | "ix": 1 1035 | }, 1036 | "s": { 1037 | "a": 0, 1038 | "k": [ 1039 | 100, 1040 | 100, 1041 | 100 1042 | ], 1043 | "ix": 6 1044 | } 1045 | }, 1046 | "ao": 0, 1047 | "shapes": [ 1048 | { 1049 | "ty": "gr", 1050 | "it": [ 1051 | { 1052 | "ty": "rc", 1053 | "d": 1, 1054 | "s": { 1055 | "a": 0, 1056 | "k": [ 1057 | 256, 1058 | 256 1059 | ], 1060 | "ix": 2 1061 | }, 1062 | "p": { 1063 | "a": 0, 1064 | "k": [ 1065 | 0, 1066 | 0 1067 | ], 1068 | "ix": 3 1069 | }, 1070 | "r": { 1071 | "a": 0, 1072 | "k": 0, 1073 | "ix": 4 1074 | }, 1075 | "nm": "Rectangle Path 1", 1076 | "mn": "ADBE Vector Shape - Rect", 1077 | "hd": false 1078 | }, 1079 | { 1080 | "ty": "tr", 1081 | "p": { 1082 | "a": 0, 1083 | "k": [ 1084 | 0, 1085 | 0 1086 | ], 1087 | "ix": 2 1088 | }, 1089 | "a": { 1090 | "a": 0, 1091 | "k": [ 1092 | 0, 1093 | 0 1094 | ], 1095 | "ix": 1 1096 | }, 1097 | "s": { 1098 | "a": 0, 1099 | "k": [ 1100 | 100, 1101 | 100 1102 | ], 1103 | "ix": 3 1104 | }, 1105 | "r": { 1106 | "a": 0, 1107 | "k": 0, 1108 | "ix": 6 1109 | }, 1110 | "o": { 1111 | "a": 0, 1112 | "k": 100, 1113 | "ix": 7 1114 | }, 1115 | "sk": { 1116 | "a": 0, 1117 | "k": 0, 1118 | "ix": 4 1119 | }, 1120 | "sa": { 1121 | "a": 0, 1122 | "k": 0, 1123 | "ix": 5 1124 | }, 1125 | "nm": "Transform" 1126 | } 1127 | ], 1128 | "nm": "bond", 1129 | "np": 1, 1130 | "cix": 2, 1131 | "ix": 1, 1132 | "mn": "ADBE Vector Group", 1133 | "hd": false 1134 | } 1135 | ], 1136 | "ip": 0, 1137 | "op": 180, 1138 | "st": 0, 1139 | "bm": 0 1140 | } 1141 | ], 1142 | "markers": [] 1143 | } -------------------------------------------------------------------------------- /app/src/main/res/raw/cloudy_weather.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": "5.1.1", 3 | "fr": 60, 4 | "ip": 0, 5 | "op": 180, 6 | "w": 256, 7 | "h": 256, 8 | "nm": "Windy", 9 | "ddd": 0, 10 | "assets": [], 11 | "layers": [ 12 | { 13 | "ddd": 0, 14 | "ind": 1, 15 | "ty": 4, 16 | "nm": "cloud", 17 | "sr": 1, 18 | "ks": { 19 | "o": { 20 | "a": 0, 21 | "k": 100, 22 | "ix": 11 23 | }, 24 | "r": { 25 | "a": 0, 26 | "k": 0, 27 | "ix": 10 28 | }, 29 | "p": { 30 | "a": 1, 31 | "k": [ 32 | { 33 | "i": { 34 | "x": 0.833, 35 | "y": 0.833 36 | }, 37 | "o": { 38 | "x": 0.167, 39 | "y": 0.167 40 | }, 41 | "n": "0p833_0p833_0p167_0p167", 42 | "t": 0, 43 | "s": [ 44 | 117.135, 45 | 125.78, 46 | 0 47 | ], 48 | "e": [ 49 | 123.135, 50 | 125.78, 51 | 0 52 | ], 53 | "to": [ 54 | 1, 55 | 0, 56 | 0 57 | ], 58 | "ti": [ 59 | 3.56038412974158e-7, 60 | 0, 61 | 0 62 | ] 63 | }, 64 | { 65 | "i": { 66 | "x": 0.833, 67 | "y": 0.833 68 | }, 69 | "o": { 70 | "x": 0.333, 71 | "y": 0 72 | }, 73 | "n": "0p833_0p833_0p333_0", 74 | "t": 45, 75 | "s": [ 76 | 123.135, 77 | 125.78, 78 | 0 79 | ], 80 | "e": [ 81 | 117.135, 82 | 125.78, 83 | 0 84 | ], 85 | "to": [ 86 | -3.56038412974158e-7, 87 | 0, 88 | 0 89 | ], 90 | "ti": [ 91 | 0.33333370089531, 92 | 0, 93 | 0 94 | ] 95 | }, 96 | { 97 | "i": { 98 | "x": 0.833, 99 | "y": 0.833 100 | }, 101 | "o": { 102 | "x": 0.333, 103 | "y": 0 104 | }, 105 | "n": "0p833_0p833_0p333_0", 106 | "t": 90, 107 | "s": [ 108 | 117.135, 109 | 125.78, 110 | 0 111 | ], 112 | "e": [ 113 | 121.135, 114 | 125.78, 115 | 0 116 | ], 117 | "to": [ 118 | -0.33333370089531, 119 | 0, 120 | 0 121 | ], 122 | "ti": [ 123 | 0, 124 | 0, 125 | 0 126 | ] 127 | }, 128 | { 129 | "i": { 130 | "x": 0.833, 131 | "y": 0.833 132 | }, 133 | "o": { 134 | "x": 0.333, 135 | "y": 0 136 | }, 137 | "n": "0p833_0p833_0p333_0", 138 | "t": 135, 139 | "s": [ 140 | 121.135, 141 | 125.78, 142 | 0 143 | ], 144 | "e": [ 145 | 117.135, 146 | 125.78, 147 | 0 148 | ], 149 | "to": [ 150 | 0, 151 | 0, 152 | 0 153 | ], 154 | "ti": [ 155 | 0.66666668653488, 156 | 0, 157 | 0 158 | ] 159 | }, 160 | { 161 | "t": 180 162 | } 163 | ], 164 | "ix": 2 165 | }, 166 | "a": { 167 | "a": 0, 168 | "k": [ 169 | 102.135, 170 | 62.78, 171 | 0 172 | ], 173 | "ix": 1 174 | }, 175 | "s": { 176 | "a": 0, 177 | "k": [ 178 | 100, 179 | 100, 180 | 100 181 | ], 182 | "ix": 6 183 | } 184 | }, 185 | "ao": 0, 186 | "shapes": [ 187 | { 188 | "ty": "gr", 189 | "it": [ 190 | { 191 | "ind": 0, 192 | "ty": "sh", 193 | "ix": 1, 194 | "ks": { 195 | "a": 0, 196 | "k": { 197 | "i": [ 198 | [ 199 | 0, 200 | 0 201 | ], 202 | [ 203 | 0, 204 | 0 205 | ], 206 | [ 207 | 0, 208 | 24.37 209 | ], 210 | [ 211 | -24.44, 212 | 0 213 | ], 214 | [ 215 | -6.12, 216 | -3.18 217 | ], 218 | [ 219 | -27.6, 220 | 0 221 | ], 222 | [ 223 | 0, 224 | -34.67 225 | ], 226 | [ 227 | 0.03, 228 | -0.7 229 | ], 230 | [ 231 | 0, 232 | -12.29 233 | ], 234 | [ 235 | 17.86, 236 | 0 237 | ], 238 | [ 239 | 0, 240 | 0 241 | ], 242 | [ 243 | 0, 244 | 0 245 | ], 246 | [ 247 | 0, 248 | 0 249 | ] 250 | ], 251 | "o": [ 252 | [ 253 | 0, 254 | 0 255 | ], 256 | [ 257 | -24.44, 258 | 0 259 | ], 260 | [ 261 | 0, 262 | -24.36 263 | ], 264 | [ 265 | 7.38, 266 | 0 267 | ], 268 | [ 269 | 8.51, 270 | -24.62 271 | ], 272 | [ 273 | 34.78, 274 | 0 275 | ], 276 | [ 277 | 0, 278 | 0.71 279 | ], 280 | [ 281 | 10.16, 282 | 5.44 283 | ], 284 | [ 285 | 0, 286 | 17.8 287 | ], 288 | [ 289 | 0, 290 | 0 291 | ], 292 | [ 293 | -0.1, 294 | 0 295 | ], 296 | [ 297 | 0, 298 | 0 299 | ], 300 | [ 301 | 0, 302 | 0 303 | ] 304 | ], 305 | "v": [ 306 | [ 307 | 123.61, 308 | 125.56 309 | ], 310 | [ 311 | 44.26, 312 | 125.56 313 | ], 314 | [ 315 | 0, 316 | 81.44 317 | ], 318 | [ 319 | 44.26, 320 | 37.33 321 | ], 322 | [ 323 | 64.71, 324 | 42.31 325 | ], 326 | [ 327 | 124.27, 328 | 0 329 | ], 330 | [ 331 | 187.25, 332 | 62.78 333 | ], 334 | [ 335 | 187.21, 336 | 64.9 337 | ], 338 | [ 339 | 204.27, 340 | 93.32 341 | ], 342 | [ 343 | 171.93, 344 | 125.56 345 | ], 346 | [ 347 | 124.27, 348 | 125.56 349 | ], 350 | [ 351 | 123.61, 352 | 125.56 353 | ], 354 | [ 355 | 124.27, 356 | 125.56 357 | ] 358 | ], 359 | "c": true 360 | }, 361 | "ix": 2 362 | }, 363 | "nm": "Path 1", 364 | "mn": "ADBE Vector Shape - Group", 365 | "hd": false 366 | }, 367 | { 368 | "ty": "fl", 369 | "c": { 370 | "a": 0, 371 | "k": [ 372 | 0.909803986549, 373 | 0.909803986549, 374 | 0.909803986549, 375 | 1 376 | ], 377 | "ix": 4 378 | }, 379 | "o": { 380 | "a": 0, 381 | "k": 100, 382 | "ix": 5 383 | }, 384 | "r": 1, 385 | "nm": "Fill 1", 386 | "mn": "ADBE Vector Graphic - Fill", 387 | "hd": false 388 | }, 389 | { 390 | "ty": "tr", 391 | "p": { 392 | "a": 0, 393 | "k": [ 394 | 0, 395 | 0 396 | ], 397 | "ix": 2 398 | }, 399 | "a": { 400 | "a": 0, 401 | "k": [ 402 | 0, 403 | 0 404 | ], 405 | "ix": 1 406 | }, 407 | "s": { 408 | "a": 0, 409 | "k": [ 410 | 100, 411 | 100 412 | ], 413 | "ix": 3 414 | }, 415 | "r": { 416 | "a": 0, 417 | "k": 0, 418 | "ix": 6 419 | }, 420 | "o": { 421 | "a": 0, 422 | "k": 100, 423 | "ix": 7 424 | }, 425 | "sk": { 426 | "a": 0, 427 | "k": 0, 428 | "ix": 4 429 | }, 430 | "sa": { 431 | "a": 0, 432 | "k": 0, 433 | "ix": 5 434 | }, 435 | "nm": "Transform" 436 | } 437 | ], 438 | "nm": "Group 1", 439 | "np": 2, 440 | "cix": 2, 441 | "ix": 1, 442 | "mn": "ADBE Vector Group", 443 | "hd": false 444 | } 445 | ], 446 | "ip": 0, 447 | "op": 180, 448 | "st": 0, 449 | "bm": 0 450 | }, 451 | { 452 | "ddd": 0, 453 | "ind": 2, 454 | "ty": 4, 455 | "nm": "cloud", 456 | "sr": 1, 457 | "ks": { 458 | "o": { 459 | "a": 0, 460 | "k": 50, 461 | "ix": 11 462 | }, 463 | "r": { 464 | "a": 0, 465 | "k": 0, 466 | "ix": 10 467 | }, 468 | "p": { 469 | "a": 1, 470 | "k": [ 471 | { 472 | "i": { 473 | "x": 0.833, 474 | "y": 0.833 475 | }, 476 | "o": { 477 | "x": 0.333, 478 | "y": 0 479 | }, 480 | "n": "0p833_0p833_0p333_0", 481 | "t": 0, 482 | "s": [ 483 | 195.37, 484 | 81.5, 485 | 0 486 | ], 487 | "e": [ 488 | 199.37, 489 | 81.5, 490 | 0 491 | ], 492 | "to": [ 493 | 0.66666668653488, 494 | 0, 495 | 0 496 | ], 497 | "ti": [ 498 | 0, 499 | 0, 500 | 0 501 | ] 502 | }, 503 | { 504 | "i": { 505 | "x": 0.833, 506 | "y": 0.833 507 | }, 508 | "o": { 509 | "x": 0.333, 510 | "y": 0 511 | }, 512 | "n": "0p833_0p833_0p333_0", 513 | "t": 35, 514 | "s": [ 515 | 199.37, 516 | 81.5, 517 | 0 518 | ], 519 | "e": [ 520 | 195.37, 521 | 81.5, 522 | 0 523 | ], 524 | "to": [ 525 | 0, 526 | 0, 527 | 0 528 | ], 529 | "ti": [ 530 | 4.57763661643185e-7, 531 | 0, 532 | 0 533 | ] 534 | }, 535 | { 536 | "i": { 537 | "x": 0.833, 538 | "y": 0.833 539 | }, 540 | "o": { 541 | "x": 0.333, 542 | "y": 0 543 | }, 544 | "n": "0p833_0p833_0p333_0", 545 | "t": 80, 546 | "s": [ 547 | 195.37, 548 | 81.5, 549 | 0 550 | ], 551 | "e": [ 552 | 199.37, 553 | 81.5, 554 | 0 555 | ], 556 | "to": [ 557 | -4.57763661643185e-7, 558 | 0, 559 | 0 560 | ], 561 | "ti": [ 562 | 0.66666668653488, 563 | 0, 564 | 0 565 | ] 566 | }, 567 | { 568 | "i": { 569 | "x": 0.833, 570 | "y": 0.833 571 | }, 572 | "o": { 573 | "x": 0.333, 574 | "y": 0 575 | }, 576 | "n": "0p833_0p833_0p333_0", 577 | "t": 125, 578 | "s": [ 579 | 199.37, 580 | 81.5, 581 | 0 582 | ], 583 | "e": [ 584 | 195.37, 585 | 81.5, 586 | 0 587 | ], 588 | "to": [ 589 | -0.64289206266403, 590 | 0, 591 | 0 592 | ], 593 | "ti": [ 594 | 0.03566187247634, 595 | 0, 596 | 0 597 | ] 598 | }, 599 | { 600 | "t": 180 601 | } 602 | ], 603 | "ix": 2 604 | }, 605 | "a": { 606 | "a": 0, 607 | "k": [ 608 | 46.37, 609 | 28.5, 610 | 0 611 | ], 612 | "ix": 1 613 | }, 614 | "s": { 615 | "a": 0, 616 | "k": [ 617 | 100, 618 | 100, 619 | 100 620 | ], 621 | "ix": 6 622 | } 623 | }, 624 | "ao": 0, 625 | "shapes": [ 626 | { 627 | "ty": "gr", 628 | "it": [ 629 | { 630 | "ind": 0, 631 | "ty": "sh", 632 | "ix": 1, 633 | "ks": { 634 | "a": 0, 635 | "k": { 636 | "i": [ 637 | [ 638 | 0, 639 | 0 640 | ], 641 | [ 642 | 0, 643 | 0 644 | ], 645 | [ 646 | 0, 647 | 11.06 648 | ], 649 | [ 650 | -11.09, 651 | 0 652 | ], 653 | [ 654 | -2.78, 655 | -1.45 656 | ], 657 | [ 658 | -12.52, 659 | 0 660 | ], 661 | [ 662 | 0, 663 | -15.74 664 | ], 665 | [ 666 | 0.01, 667 | -0.32 668 | ], 669 | [ 670 | 0, 671 | -5.58 672 | ], 673 | [ 674 | 8.11, 675 | 0 676 | ], 677 | [ 678 | 0, 679 | 0 680 | ], 681 | [ 682 | 0, 683 | 0 684 | ], 685 | [ 686 | 0, 687 | 0 688 | ] 689 | ], 690 | "o": [ 691 | [ 692 | 0, 693 | 0 694 | ], 695 | [ 696 | -11.09, 697 | 0 698 | ], 699 | [ 700 | 0, 701 | -11.06 702 | ], 703 | [ 704 | 3.35, 705 | 0 706 | ], 707 | [ 708 | 3.86, 709 | -11.18 710 | ], 711 | [ 712 | 15.8, 713 | 0 714 | ], 715 | [ 716 | 0, 717 | 0.32 718 | ], 719 | [ 720 | 4.61, 721 | 2.47 722 | ], 723 | [ 724 | 0, 725 | 8.09 726 | ], 727 | [ 728 | 0, 729 | 0 730 | ], 731 | [ 732 | -0.04, 733 | 0 734 | ], 735 | [ 736 | 0, 737 | 0 738 | ], 739 | [ 740 | 0, 741 | 0 742 | ] 743 | ], 744 | "v": [ 745 | [ 746 | 56.11, 747 | 57 748 | ], 749 | [ 750 | 20.09, 751 | 57 752 | ], 753 | [ 754 | 0, 755 | 36.97 756 | ], 757 | [ 758 | 20.09, 759 | 16.95 760 | ], 761 | [ 762 | 29.38, 763 | 19.21 764 | ], 765 | [ 766 | 56.41, 767 | 0 768 | ], 769 | [ 770 | 85.01, 771 | 28.5 772 | ], 773 | [ 774 | 84.99, 775 | 29.46 776 | ], 777 | [ 778 | 92.74, 779 | 42.36 780 | ], 781 | [ 782 | 78.05, 783 | 57 784 | ], 785 | [ 786 | 56.41, 787 | 57 788 | ], 789 | [ 790 | 56.11, 791 | 57 792 | ], 793 | [ 794 | 56.41, 795 | 57 796 | ] 797 | ], 798 | "c": true 799 | }, 800 | "ix": 2 801 | }, 802 | "nm": "Path 1", 803 | "mn": "ADBE Vector Shape - Group", 804 | "hd": false 805 | }, 806 | { 807 | "ty": "fl", 808 | "c": { 809 | "a": 0, 810 | "k": [ 811 | 0.909803986549, 812 | 0.909803986549, 813 | 0.909803986549, 814 | 1 815 | ], 816 | "ix": 4 817 | }, 818 | "o": { 819 | "a": 0, 820 | "k": 100, 821 | "ix": 5 822 | }, 823 | "r": 1, 824 | "nm": "Fill 1", 825 | "mn": "ADBE Vector Graphic - Fill", 826 | "hd": false 827 | }, 828 | { 829 | "ty": "tr", 830 | "p": { 831 | "a": 0, 832 | "k": [ 833 | 0, 834 | 0 835 | ], 836 | "ix": 2 837 | }, 838 | "a": { 839 | "a": 0, 840 | "k": [ 841 | 0, 842 | 0 843 | ], 844 | "ix": 1 845 | }, 846 | "s": { 847 | "a": 0, 848 | "k": [ 849 | 100, 850 | 100 851 | ], 852 | "ix": 3 853 | }, 854 | "r": { 855 | "a": 0, 856 | "k": 0, 857 | "ix": 6 858 | }, 859 | "o": { 860 | "a": 0, 861 | "k": 100, 862 | "ix": 7 863 | }, 864 | "sk": { 865 | "a": 0, 866 | "k": 0, 867 | "ix": 4 868 | }, 869 | "sa": { 870 | "a": 0, 871 | "k": 0, 872 | "ix": 5 873 | }, 874 | "nm": "Transform" 875 | } 876 | ], 877 | "nm": "Group 1", 878 | "np": 2, 879 | "cix": 2, 880 | "ix": 1, 881 | "mn": "ADBE Vector Group", 882 | "hd": false 883 | } 884 | ], 885 | "ip": 0, 886 | "op": 180, 887 | "st": 0, 888 | "bm": 0 889 | }, 890 | { 891 | "ddd": 0, 892 | "ind": 3, 893 | "ty": 4, 894 | "nm": "bond", 895 | "sr": 1, 896 | "ks": { 897 | "o": { 898 | "a": 0, 899 | "k": 100, 900 | "ix": 11 901 | }, 902 | "r": { 903 | "a": 0, 904 | "k": 0, 905 | "ix": 10 906 | }, 907 | "p": { 908 | "a": 0, 909 | "k": [ 910 | 128, 911 | 128, 912 | 0 913 | ], 914 | "ix": 2 915 | }, 916 | "a": { 917 | "a": 0, 918 | "k": [ 919 | 0, 920 | 0, 921 | 0 922 | ], 923 | "ix": 1 924 | }, 925 | "s": { 926 | "a": 0, 927 | "k": [ 928 | 100, 929 | 100, 930 | 100 931 | ], 932 | "ix": 6 933 | } 934 | }, 935 | "ao": 0, 936 | "shapes": [ 937 | { 938 | "ty": "gr", 939 | "it": [ 940 | { 941 | "ty": "rc", 942 | "d": 1, 943 | "s": { 944 | "a": 0, 945 | "k": [ 946 | 256, 947 | 256 948 | ], 949 | "ix": 2 950 | }, 951 | "p": { 952 | "a": 0, 953 | "k": [ 954 | 0, 955 | 0 956 | ], 957 | "ix": 3 958 | }, 959 | "r": { 960 | "a": 0, 961 | "k": 0, 962 | "ix": 4 963 | }, 964 | "nm": "Rectangle Path 1", 965 | "mn": "ADBE Vector Shape - Rect", 966 | "hd": false 967 | }, 968 | { 969 | "ty": "tr", 970 | "p": { 971 | "a": 0, 972 | "k": [ 973 | 0, 974 | 0 975 | ], 976 | "ix": 2 977 | }, 978 | "a": { 979 | "a": 0, 980 | "k": [ 981 | 0, 982 | 0 983 | ], 984 | "ix": 1 985 | }, 986 | "s": { 987 | "a": 0, 988 | "k": [ 989 | 100, 990 | 100 991 | ], 992 | "ix": 3 993 | }, 994 | "r": { 995 | "a": 0, 996 | "k": 0, 997 | "ix": 6 998 | }, 999 | "o": { 1000 | "a": 0, 1001 | "k": 100, 1002 | "ix": 7 1003 | }, 1004 | "sk": { 1005 | "a": 0, 1006 | "k": 0, 1007 | "ix": 4 1008 | }, 1009 | "sa": { 1010 | "a": 0, 1011 | "k": 0, 1012 | "ix": 5 1013 | }, 1014 | "nm": "Transform" 1015 | } 1016 | ], 1017 | "nm": "bond", 1018 | "np": 1, 1019 | "cix": 2, 1020 | "ix": 1, 1021 | "mn": "ADBE Vector Group", 1022 | "hd": false 1023 | } 1024 | ], 1025 | "ip": 0, 1026 | "op": 180, 1027 | "st": 0, 1028 | "bm": 0 1029 | } 1030 | ], 1031 | "markers": [] 1032 | } -------------------------------------------------------------------------------- /app/src/main/res/raw/few_clouds.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": "5.1.1", 3 | "fr": 60, 4 | "ip": 0, 5 | "op": 180, 6 | "w": 256, 7 | "h": 256, 8 | "nm": "PartlyCloudyDay", 9 | "ddd": 0, 10 | "assets": [], 11 | "layers": [ 12 | { 13 | "ddd": 0, 14 | "ind": 1, 15 | "ty": 4, 16 | "nm": "cloud", 17 | "sr": 1, 18 | "ks": { 19 | "o": { 20 | "a": 0, 21 | "k": 100, 22 | "ix": 11 23 | }, 24 | "r": { 25 | "a": 0, 26 | "k": 0, 27 | "ix": 10 28 | }, 29 | "p": { 30 | "a": 1, 31 | "k": [ 32 | { 33 | "i": { 34 | "x": 0.833, 35 | "y": 0.833 36 | }, 37 | "o": { 38 | "x": 0.333, 39 | "y": 0 40 | }, 41 | "n": "0p833_0p833_0p333_0", 42 | "t": 0, 43 | "s": [ 44 | 76.83, 45 | 63.21, 46 | 0 47 | ], 48 | "e": [ 49 | 78.83, 50 | 63.21, 51 | 0 52 | ], 53 | "to": [ 54 | 0.33333334326744, 55 | 0, 56 | 0 57 | ], 58 | "ti": [ 59 | 0, 60 | 0, 61 | 0 62 | ] 63 | }, 64 | { 65 | "i": { 66 | "x": 0.833, 67 | "y": 0.833 68 | }, 69 | "o": { 70 | "x": 0.333, 71 | "y": 0 72 | }, 73 | "n": "0p833_0p833_0p333_0", 74 | "t": 45, 75 | "s": [ 76 | 78.83, 77 | 63.21, 78 | 0 79 | ], 80 | "e": [ 81 | 76.83, 82 | 63.21, 83 | 0 84 | ], 85 | "to": [ 86 | 0, 87 | 0, 88 | 0 89 | ], 90 | "ti": [ 91 | 0, 92 | 0, 93 | 0 94 | ] 95 | }, 96 | { 97 | "i": { 98 | "x": 0.833, 99 | "y": 0.833 100 | }, 101 | "o": { 102 | "x": 0.333, 103 | "y": 0 104 | }, 105 | "n": "0p833_0p833_0p333_0", 106 | "t": 90, 107 | "s": [ 108 | 76.83, 109 | 63.21, 110 | 0 111 | ], 112 | "e": [ 113 | 78.83, 114 | 63.21, 115 | 0 116 | ], 117 | "to": [ 118 | 0, 119 | 0, 120 | 0 121 | ], 122 | "ti": [ 123 | 0, 124 | 0, 125 | 0 126 | ] 127 | }, 128 | { 129 | "i": { 130 | "x": 0.833, 131 | "y": 0.833 132 | }, 133 | "o": { 134 | "x": 0.333, 135 | "y": 0 136 | }, 137 | "n": "0p833_0p833_0p333_0", 138 | "t": 135, 139 | "s": [ 140 | 78.83, 141 | 63.21, 142 | 0 143 | ], 144 | "e": [ 145 | 76.83, 146 | 63.21, 147 | 0 148 | ], 149 | "to": [ 150 | 0, 151 | 0, 152 | 0 153 | ], 154 | "ti": [ 155 | 0.33333334326744, 156 | 0, 157 | 0 158 | ] 159 | }, 160 | { 161 | "t": 180 162 | } 163 | ], 164 | "ix": 2 165 | }, 166 | "a": { 167 | "a": 0, 168 | "k": [ 169 | 45.49, 170 | 27.05, 171 | 0 172 | ], 173 | "ix": 1 174 | }, 175 | "s": { 176 | "a": 0, 177 | "k": [ 178 | 100, 179 | 100, 180 | 100 181 | ], 182 | "ix": 6 183 | } 184 | }, 185 | "ao": 0, 186 | "shapes": [ 187 | { 188 | "ty": "gr", 189 | "it": [ 190 | { 191 | "ind": 0, 192 | "ty": "sh", 193 | "ix": 1, 194 | "ks": { 195 | "a": 0, 196 | "k": { 197 | "i": [ 198 | [ 199 | 0, 200 | 0 201 | ], 202 | [ 203 | 0, 204 | 0 205 | ], 206 | [ 207 | 0, 208 | 10.5 209 | ], 210 | [ 211 | -10.88, 212 | 0 213 | ], 214 | [ 215 | -2.72, 216 | -1.37 217 | ], 218 | [ 219 | -12.29, 220 | 0 221 | ], 222 | [ 223 | 0, 224 | -14.94 225 | ], 226 | [ 227 | 0.01, 228 | -0.3 229 | ], 230 | [ 231 | 0, 232 | -5.3 233 | ], 234 | [ 235 | 7.96, 236 | 0 237 | ], 238 | [ 239 | 0, 240 | 0 241 | ], 242 | [ 243 | 0, 244 | 0 245 | ], 246 | [ 247 | 0, 248 | 0 249 | ] 250 | ], 251 | "o": [ 252 | [ 253 | 0, 254 | 0 255 | ], 256 | [ 257 | -10.88, 258 | 0 259 | ], 260 | [ 261 | 0, 262 | -10.5 263 | ], 264 | [ 265 | 3.29, 266 | 0 267 | ], 268 | [ 269 | 3.79, 270 | -10.61 271 | ], 272 | [ 273 | 15.49, 274 | 0 275 | ], 276 | [ 277 | 0, 278 | 0.31 279 | ], 280 | [ 281 | 4.52, 282 | 2.35 283 | ], 284 | [ 285 | 0, 286 | 7.67 287 | ], 288 | [ 289 | 0, 290 | 0 291 | ], 292 | [ 293 | -0.05, 294 | 0 295 | ], 296 | [ 297 | 0, 298 | 0 299 | ], 300 | [ 301 | 0, 302 | 0 303 | ] 304 | ], 305 | "v": [ 306 | [ 307 | 55.05, 308 | 54.1 309 | ], 310 | [ 311 | 19.71, 312 | 54.1 313 | ], 314 | [ 315 | 0, 316 | 35.09 317 | ], 318 | [ 319 | 19.71, 320 | 16.08 321 | ], 322 | [ 323 | 28.82, 324 | 18.23 325 | ], 326 | [ 327 | 55.35, 328 | 0 329 | ], 330 | [ 331 | 83.4, 332 | 27.05 333 | ], 334 | [ 335 | 83.38, 336 | 27.96 337 | ], 338 | [ 339 | 90.98, 340 | 40.21 341 | ], 342 | [ 343 | 76.57, 344 | 54.1 345 | ], 346 | [ 347 | 55.35, 348 | 54.1 349 | ], 350 | [ 351 | 55.05, 352 | 54.1 353 | ], 354 | [ 355 | 55.35, 356 | 54.1 357 | ] 358 | ], 359 | "c": true 360 | }, 361 | "ix": 2 362 | }, 363 | "nm": "Path 1", 364 | "mn": "ADBE Vector Shape - Group", 365 | "hd": false 366 | }, 367 | { 368 | "ty": "st", 369 | "c": { 370 | "a": 0, 371 | "k": [ 372 | 1, 373 | 1, 374 | 1, 375 | 1 376 | ], 377 | "ix": 3 378 | }, 379 | "o": { 380 | "a": 0, 381 | "k": 100, 382 | "ix": 4 383 | }, 384 | "w": { 385 | "a": 0, 386 | "k": 7, 387 | "ix": 5 388 | }, 389 | "lc": 1, 390 | "lj": 1, 391 | "ml": 4, 392 | "nm": "Stroke 1", 393 | "mn": "ADBE Vector Graphic - Stroke", 394 | "hd": false 395 | }, 396 | { 397 | "ty": "fl", 398 | "c": { 399 | "a": 0, 400 | "k": [ 401 | 0.909803986549, 402 | 0.909803986549, 403 | 0.909803986549, 404 | 1 405 | ], 406 | "ix": 4 407 | }, 408 | "o": { 409 | "a": 0, 410 | "k": 100, 411 | "ix": 5 412 | }, 413 | "r": 1, 414 | "nm": "Fill 1", 415 | "mn": "ADBE Vector Graphic - Fill", 416 | "hd": false 417 | }, 418 | { 419 | "ty": "tr", 420 | "p": { 421 | "a": 0, 422 | "k": [ 423 | 0, 424 | 0 425 | ], 426 | "ix": 2 427 | }, 428 | "a": { 429 | "a": 0, 430 | "k": [ 431 | 0, 432 | 0 433 | ], 434 | "ix": 1 435 | }, 436 | "s": { 437 | "a": 0, 438 | "k": [ 439 | 100, 440 | 100 441 | ], 442 | "ix": 3 443 | }, 444 | "r": { 445 | "a": 0, 446 | "k": 0, 447 | "ix": 6 448 | }, 449 | "o": { 450 | "a": 0, 451 | "k": 100, 452 | "ix": 7 453 | }, 454 | "sk": { 455 | "a": 0, 456 | "k": 0, 457 | "ix": 4 458 | }, 459 | "sa": { 460 | "a": 0, 461 | "k": 0, 462 | "ix": 5 463 | }, 464 | "nm": "Transform" 465 | } 466 | ], 467 | "nm": "Group 1", 468 | "np": 3, 469 | "cix": 2, 470 | "ix": 1, 471 | "mn": "ADBE Vector Group", 472 | "hd": false 473 | } 474 | ], 475 | "ip": 0, 476 | "op": 180, 477 | "st": 0, 478 | "bm": 0 479 | }, 480 | { 481 | "ddd": 0, 482 | "ind": 2, 483 | "ty": 4, 484 | "nm": "cloud", 485 | "sr": 1, 486 | "ks": { 487 | "o": { 488 | "a": 0, 489 | "k": 100, 490 | "ix": 11 491 | }, 492 | "r": { 493 | "a": 0, 494 | "k": 0, 495 | "ix": 10 496 | }, 497 | "p": { 498 | "a": 1, 499 | "k": [ 500 | { 501 | "i": { 502 | "x": 0.833, 503 | "y": 0.833 504 | }, 505 | "o": { 506 | "x": 0.333, 507 | "y": 0 508 | }, 509 | "n": "0p833_0p833_0p333_0", 510 | "t": 0, 511 | "s": [ 512 | 50.49, 513 | 183.99, 514 | 0 515 | ], 516 | "e": [ 517 | 53.49, 518 | 183.99, 519 | 0 520 | ], 521 | "to": [ 522 | 0.5, 523 | 0, 524 | 0 525 | ], 526 | "ti": [ 527 | -3.56038412974158e-7, 528 | 0, 529 | 0 530 | ] 531 | }, 532 | { 533 | "i": { 534 | "x": 0.833, 535 | "y": 0.833 536 | }, 537 | "o": { 538 | "x": 0.333, 539 | "y": 0 540 | }, 541 | "n": "0p833_0p833_0p333_0", 542 | "t": 40, 543 | "s": [ 544 | 53.49, 545 | 183.99, 546 | 0 547 | ], 548 | "e": [ 549 | 50.49, 550 | 183.99, 551 | 0 552 | ], 553 | "to": [ 554 | 3.56038412974158e-7, 555 | 0, 556 | 0 557 | ], 558 | "ti": [ 559 | -3.56038412974158e-7, 560 | 0, 561 | 0 562 | ] 563 | }, 564 | { 565 | "i": { 566 | "x": 0.833, 567 | "y": 0.833 568 | }, 569 | "o": { 570 | "x": 0.333, 571 | "y": 0 572 | }, 573 | "n": "0p833_0p833_0p333_0", 574 | "t": 85, 575 | "s": [ 576 | 50.49, 577 | 183.99, 578 | 0 579 | ], 580 | "e": [ 581 | 53.49, 582 | 183.99, 583 | 0 584 | ], 585 | "to": [ 586 | 3.56038412974158e-7, 587 | 0, 588 | 0 589 | ], 590 | "ti": [ 591 | 0, 592 | 0, 593 | 0 594 | ] 595 | }, 596 | { 597 | "i": { 598 | "x": 0.833, 599 | "y": 0.833 600 | }, 601 | "o": { 602 | "x": 0.333, 603 | "y": 0 604 | }, 605 | "n": "0p833_0p833_0p333_0", 606 | "t": 130, 607 | "s": [ 608 | 53.49, 609 | 183.99, 610 | 0 611 | ], 612 | "e": [ 613 | 50.49, 614 | 183.99, 615 | 0 616 | ], 617 | "to": [ 618 | 0, 619 | 0, 620 | 0 621 | ], 622 | "ti": [ 623 | 0.5, 624 | 0, 625 | 0 626 | ] 627 | }, 628 | { 629 | "t": 180 630 | } 631 | ], 632 | "ix": 2 633 | }, 634 | "a": { 635 | "a": 0, 636 | "k": [ 637 | 45.49, 638 | 27.05, 639 | 0 640 | ], 641 | "ix": 1 642 | }, 643 | "s": { 644 | "a": 0, 645 | "k": [ 646 | 100, 647 | 100, 648 | 100 649 | ], 650 | "ix": 6 651 | } 652 | }, 653 | "ao": 0, 654 | "shapes": [ 655 | { 656 | "ty": "gr", 657 | "it": [ 658 | { 659 | "ind": 0, 660 | "ty": "sh", 661 | "ix": 1, 662 | "ks": { 663 | "a": 0, 664 | "k": { 665 | "i": [ 666 | [ 667 | 0, 668 | 0 669 | ], 670 | [ 671 | 0, 672 | 0 673 | ], 674 | [ 675 | 0, 676 | 10.5 677 | ], 678 | [ 679 | -10.88, 680 | 0 681 | ], 682 | [ 683 | -2.72, 684 | -1.37 685 | ], 686 | [ 687 | -12.29, 688 | 0 689 | ], 690 | [ 691 | 0, 692 | -14.94 693 | ], 694 | [ 695 | 0.01, 696 | -0.3 697 | ], 698 | [ 699 | 0, 700 | -5.3 701 | ], 702 | [ 703 | 7.96, 704 | 0 705 | ], 706 | [ 707 | 0, 708 | 0 709 | ], 710 | [ 711 | 0, 712 | 0 713 | ], 714 | [ 715 | 0, 716 | 0 717 | ] 718 | ], 719 | "o": [ 720 | [ 721 | 0, 722 | 0 723 | ], 724 | [ 725 | -10.88, 726 | 0 727 | ], 728 | [ 729 | 0, 730 | -10.5 731 | ], 732 | [ 733 | 3.29, 734 | 0 735 | ], 736 | [ 737 | 3.79, 738 | -10.61 739 | ], 740 | [ 741 | 15.49, 742 | 0 743 | ], 744 | [ 745 | 0, 746 | 0.31 747 | ], 748 | [ 749 | 4.52, 750 | 2.35 751 | ], 752 | [ 753 | 0, 754 | 7.67 755 | ], 756 | [ 757 | 0, 758 | 0 759 | ], 760 | [ 761 | -0.05, 762 | 0 763 | ], 764 | [ 765 | 0, 766 | 0 767 | ], 768 | [ 769 | 0, 770 | 0 771 | ] 772 | ], 773 | "v": [ 774 | [ 775 | 55.05, 776 | 54.1 777 | ], 778 | [ 779 | 19.71, 780 | 54.1 781 | ], 782 | [ 783 | 0, 784 | 35.09 785 | ], 786 | [ 787 | 19.71, 788 | 16.08 789 | ], 790 | [ 791 | 28.82, 792 | 18.23 793 | ], 794 | [ 795 | 55.35, 796 | 0 797 | ], 798 | [ 799 | 83.4, 800 | 27.05 801 | ], 802 | [ 803 | 83.38, 804 | 27.96 805 | ], 806 | [ 807 | 90.98, 808 | 40.21 809 | ], 810 | [ 811 | 76.57, 812 | 54.1 813 | ], 814 | [ 815 | 55.35, 816 | 54.1 817 | ], 818 | [ 819 | 55.05, 820 | 54.1 821 | ], 822 | [ 823 | 55.35, 824 | 54.1 825 | ] 826 | ], 827 | "c": true 828 | }, 829 | "ix": 2 830 | }, 831 | "nm": "Path 1", 832 | "mn": "ADBE Vector Shape - Group", 833 | "hd": false 834 | }, 835 | { 836 | "ty": "st", 837 | "c": { 838 | "a": 0, 839 | "k": [ 840 | 1, 841 | 1, 842 | 1, 843 | 1 844 | ], 845 | "ix": 3 846 | }, 847 | "o": { 848 | "a": 0, 849 | "k": 100, 850 | "ix": 4 851 | }, 852 | "w": { 853 | "a": 0, 854 | "k": 7, 855 | "ix": 5 856 | }, 857 | "lc": 1, 858 | "lj": 1, 859 | "ml": 4, 860 | "nm": "Stroke 1", 861 | "mn": "ADBE Vector Graphic - Stroke", 862 | "hd": false 863 | }, 864 | { 865 | "ty": "fl", 866 | "c": { 867 | "a": 0, 868 | "k": [ 869 | 0.909803986549, 870 | 0.909803986549, 871 | 0.909803986549, 872 | 1 873 | ], 874 | "ix": 4 875 | }, 876 | "o": { 877 | "a": 0, 878 | "k": 100, 879 | "ix": 5 880 | }, 881 | "r": 1, 882 | "nm": "Fill 1", 883 | "mn": "ADBE Vector Graphic - Fill", 884 | "hd": false 885 | }, 886 | { 887 | "ty": "tr", 888 | "p": { 889 | "a": 0, 890 | "k": [ 891 | 0, 892 | 0 893 | ], 894 | "ix": 2 895 | }, 896 | "a": { 897 | "a": 0, 898 | "k": [ 899 | 0, 900 | 0 901 | ], 902 | "ix": 1 903 | }, 904 | "s": { 905 | "a": 0, 906 | "k": [ 907 | 100, 908 | 100 909 | ], 910 | "ix": 3 911 | }, 912 | "r": { 913 | "a": 0, 914 | "k": 0, 915 | "ix": 6 916 | }, 917 | "o": { 918 | "a": 0, 919 | "k": 100, 920 | "ix": 7 921 | }, 922 | "sk": { 923 | "a": 0, 924 | "k": 0, 925 | "ix": 4 926 | }, 927 | "sa": { 928 | "a": 0, 929 | "k": 0, 930 | "ix": 5 931 | }, 932 | "nm": "Transform" 933 | } 934 | ], 935 | "nm": "Group 1", 936 | "np": 3, 937 | "cix": 2, 938 | "ix": 1, 939 | "mn": "ADBE Vector Group", 940 | "hd": false 941 | } 942 | ], 943 | "ip": 0, 944 | "op": 180, 945 | "st": 0, 946 | "bm": 0 947 | }, 948 | { 949 | "ddd": 0, 950 | "ind": 3, 951 | "ty": 4, 952 | "nm": "cloud", 953 | "sr": 1, 954 | "ks": { 955 | "o": { 956 | "a": 0, 957 | "k": 100, 958 | "ix": 11 959 | }, 960 | "r": { 961 | "a": 0, 962 | "k": 0, 963 | "ix": 10 964 | }, 965 | "p": { 966 | "a": 1, 967 | "k": [ 968 | { 969 | "i": { 970 | "x": 0.833, 971 | "y": 0.833 972 | }, 973 | "o": { 974 | "x": 0.333, 975 | "y": 0 976 | }, 977 | "n": "0p833_0p833_0p333_0", 978 | "t": 0, 979 | "s": [ 980 | 182.765, 981 | 116.19, 982 | 0 983 | ], 984 | "e": [ 985 | 186.765, 986 | 116.19, 987 | 0 988 | ], 989 | "to": [ 990 | 0.66666668653488, 991 | 0, 992 | 0 993 | ], 994 | "ti": [ 995 | 0, 996 | 0, 997 | 0 998 | ] 999 | }, 1000 | { 1001 | "i": { 1002 | "x": 0.833, 1003 | "y": 0.833 1004 | }, 1005 | "o": { 1006 | "x": 0.333, 1007 | "y": 0 1008 | }, 1009 | "n": "0p833_0p833_0p333_0", 1010 | "t": 50, 1011 | "s": [ 1012 | 186.765, 1013 | 116.19, 1014 | 0 1015 | ], 1016 | "e": [ 1017 | 182.765, 1018 | 116.19, 1019 | 0 1020 | ], 1021 | "to": [ 1022 | 0, 1023 | 0, 1024 | 0 1025 | ], 1026 | "ti": [ 1027 | 0, 1028 | 0, 1029 | 0 1030 | ] 1031 | }, 1032 | { 1033 | "i": { 1034 | "x": 0.833, 1035 | "y": 0.833 1036 | }, 1037 | "o": { 1038 | "x": 0.333, 1039 | "y": 0 1040 | }, 1041 | "n": "0p833_0p833_0p333_0", 1042 | "t": 95, 1043 | "s": [ 1044 | 182.765, 1045 | 116.19, 1046 | 0 1047 | ], 1048 | "e": [ 1049 | 186.765, 1050 | 116.19, 1051 | 0 1052 | ], 1053 | "to": [ 1054 | 0, 1055 | 0, 1056 | 0 1057 | ], 1058 | "ti": [ 1059 | -1.01725255774454e-7, 1060 | 0, 1061 | 0 1062 | ] 1063 | }, 1064 | { 1065 | "i": { 1066 | "x": 0.833, 1067 | "y": 0.833 1068 | }, 1069 | "o": { 1070 | "x": 0.333, 1071 | "y": 0 1072 | }, 1073 | "n": "0p833_0p833_0p333_0", 1074 | "t": 140, 1075 | "s": [ 1076 | 186.765, 1077 | 116.19, 1078 | 0 1079 | ], 1080 | "e": [ 1081 | 182.765, 1082 | 116.19, 1083 | 0 1084 | ], 1085 | "to": [ 1086 | 1.01725255774454e-7, 1087 | 0, 1088 | 0 1089 | ], 1090 | "ti": [ 1091 | 0.66666656732559, 1092 | 0, 1093 | 0 1094 | ] 1095 | }, 1096 | { 1097 | "t": 180 1098 | } 1099 | ], 1100 | "ix": 2 1101 | }, 1102 | "a": { 1103 | "a": 0, 1104 | "k": [ 1105 | 60.235, 1106 | 35.82, 1107 | 0 1108 | ], 1109 | "ix": 1 1110 | }, 1111 | "s": { 1112 | "a": 0, 1113 | "k": [ 1114 | 100, 1115 | 100, 1116 | 100 1117 | ], 1118 | "ix": 6 1119 | } 1120 | }, 1121 | "ao": 0, 1122 | "shapes": [ 1123 | { 1124 | "ty": "gr", 1125 | "it": [ 1126 | { 1127 | "ind": 0, 1128 | "ty": "sh", 1129 | "ix": 1, 1130 | "ks": { 1131 | "a": 0, 1132 | "k": { 1133 | "i": [ 1134 | [ 1135 | 0, 1136 | 0 1137 | ], 1138 | [ 1139 | 0, 1140 | 0 1141 | ], 1142 | [ 1143 | 0, 1144 | 13.9 1145 | ], 1146 | [ 1147 | -14.41, 1148 | 0 1149 | ], 1150 | [ 1151 | -3.61, 1152 | -1.82 1153 | ], 1154 | [ 1155 | -16.28, 1156 | 0 1157 | ], 1158 | [ 1159 | 0, 1160 | -19.78 1161 | ], 1162 | [ 1163 | 0.01, 1164 | -0.4 1165 | ], 1166 | [ 1167 | 0, 1168 | -7.01 1169 | ], 1170 | [ 1171 | 10.53, 1172 | 0 1173 | ], 1174 | [ 1175 | 0, 1176 | 0 1177 | ], 1178 | [ 1179 | 0, 1180 | 0 1181 | ], 1182 | [ 1183 | 0, 1184 | 0 1185 | ] 1186 | ], 1187 | "o": [ 1188 | [ 1189 | 0, 1190 | 0 1191 | ], 1192 | [ 1193 | -14.41, 1194 | 0 1195 | ], 1196 | [ 1197 | 0, 1198 | -13.9 1199 | ], 1200 | [ 1201 | 4.35, 1202 | 0 1203 | ], 1204 | [ 1205 | 5.02, 1206 | -14.05 1207 | ], 1208 | [ 1209 | 20.51, 1210 | 0 1211 | ], 1212 | [ 1213 | 0, 1214 | 0.4 1215 | ], 1216 | [ 1217 | 5.99, 1218 | 3.1 1219 | ], 1220 | [ 1221 | 0, 1222 | 10.16 1223 | ], 1224 | [ 1225 | 0, 1226 | 0 1227 | ], 1228 | [ 1229 | -0.06, 1230 | 0 1231 | ], 1232 | [ 1233 | 0, 1234 | 0 1235 | ], 1236 | [ 1237 | 0, 1238 | 0 1239 | ] 1240 | ], 1241 | "v": [ 1242 | [ 1243 | 72.9, 1244 | 71.64 1245 | ], 1246 | [ 1247 | 26.1, 1248 | 71.64 1249 | ], 1250 | [ 1251 | 0, 1252 | 46.47 1253 | ], 1254 | [ 1255 | 26.1, 1256 | 21.3 1257 | ], 1258 | [ 1259 | 38.16, 1260 | 24.14 1261 | ], 1262 | [ 1263 | 73.29, 1264 | 0 1265 | ], 1266 | [ 1267 | 110.43, 1268 | 35.82 1269 | ], 1270 | [ 1271 | 110.41, 1272 | 37.03 1273 | ], 1274 | [ 1275 | 120.47, 1276 | 53.24 1277 | ], 1278 | [ 1279 | 101.4, 1280 | 71.64 1281 | ], 1282 | [ 1283 | 73.29, 1284 | 71.64 1285 | ], 1286 | [ 1287 | 72.9, 1288 | 71.64 1289 | ], 1290 | [ 1291 | 73.29, 1292 | 71.64 1293 | ] 1294 | ], 1295 | "c": true 1296 | }, 1297 | "ix": 2 1298 | }, 1299 | "nm": "Path 1", 1300 | "mn": "ADBE Vector Shape - Group", 1301 | "hd": false 1302 | }, 1303 | { 1304 | "ty": "st", 1305 | "c": { 1306 | "a": 0, 1307 | "k": [ 1308 | 1, 1309 | 1, 1310 | 1, 1311 | 1 1312 | ], 1313 | "ix": 3 1314 | }, 1315 | "o": { 1316 | "a": 0, 1317 | "k": 100, 1318 | "ix": 4 1319 | }, 1320 | "w": { 1321 | "a": 0, 1322 | "k": 7, 1323 | "ix": 5 1324 | }, 1325 | "lc": 1, 1326 | "lj": 1, 1327 | "ml": 4, 1328 | "nm": "Stroke 1", 1329 | "mn": "ADBE Vector Graphic - Stroke", 1330 | "hd": false 1331 | }, 1332 | { 1333 | "ty": "fl", 1334 | "c": { 1335 | "a": 0, 1336 | "k": [ 1337 | 0.909803986549, 1338 | 0.909803986549, 1339 | 0.909803986549, 1340 | 1 1341 | ], 1342 | "ix": 4 1343 | }, 1344 | "o": { 1345 | "a": 0, 1346 | "k": 100, 1347 | "ix": 5 1348 | }, 1349 | "r": 1, 1350 | "nm": "Fill 1", 1351 | "mn": "ADBE Vector Graphic - Fill", 1352 | "hd": false 1353 | }, 1354 | { 1355 | "ty": "tr", 1356 | "p": { 1357 | "a": 0, 1358 | "k": [ 1359 | 0, 1360 | 0 1361 | ], 1362 | "ix": 2 1363 | }, 1364 | "a": { 1365 | "a": 0, 1366 | "k": [ 1367 | 0, 1368 | 0 1369 | ], 1370 | "ix": 1 1371 | }, 1372 | "s": { 1373 | "a": 0, 1374 | "k": [ 1375 | 100, 1376 | 100 1377 | ], 1378 | "ix": 3 1379 | }, 1380 | "r": { 1381 | "a": 0, 1382 | "k": 0, 1383 | "ix": 6 1384 | }, 1385 | "o": { 1386 | "a": 0, 1387 | "k": 100, 1388 | "ix": 7 1389 | }, 1390 | "sk": { 1391 | "a": 0, 1392 | "k": 0, 1393 | "ix": 4 1394 | }, 1395 | "sa": { 1396 | "a": 0, 1397 | "k": 0, 1398 | "ix": 5 1399 | }, 1400 | "nm": "Transform" 1401 | } 1402 | ], 1403 | "nm": "Group 1", 1404 | "np": 3, 1405 | "cix": 2, 1406 | "ix": 1, 1407 | "mn": "ADBE Vector Group", 1408 | "hd": false 1409 | } 1410 | ], 1411 | "ip": 0, 1412 | "op": 180, 1413 | "st": 0, 1414 | "bm": 0 1415 | }, 1416 | { 1417 | "ddd": 0, 1418 | "ind": 4, 1419 | "ty": 4, 1420 | "nm": "sun", 1421 | "sr": 1, 1422 | "ks": { 1423 | "o": { 1424 | "a": 0, 1425 | "k": 100, 1426 | "ix": 11 1427 | }, 1428 | "r": { 1429 | "a": 0, 1430 | "k": 0, 1431 | "ix": 10 1432 | }, 1433 | "p": { 1434 | "a": 0, 1435 | "k": [ 1436 | 129.275, 1437 | 127.375, 1438 | 0 1439 | ], 1440 | "ix": 2 1441 | }, 1442 | "a": { 1443 | "a": 0, 1444 | "k": [ 1445 | 0, 1446 | 0, 1447 | 0 1448 | ], 1449 | "ix": 1 1450 | }, 1451 | "s": { 1452 | "a": 0, 1453 | "k": [ 1454 | 100, 1455 | 100, 1456 | 100 1457 | ], 1458 | "ix": 6 1459 | } 1460 | }, 1461 | "ao": 0, 1462 | "shapes": [ 1463 | { 1464 | "ty": "gr", 1465 | "it": [ 1466 | { 1467 | "d": 1, 1468 | "ty": "el", 1469 | "s": { 1470 | "a": 0, 1471 | "k": [ 1472 | 170.59, 1473 | 169.85 1474 | ], 1475 | "ix": 2 1476 | }, 1477 | "p": { 1478 | "a": 0, 1479 | "k": [ 1480 | 0, 1481 | 0 1482 | ], 1483 | "ix": 3 1484 | }, 1485 | "nm": "Ellipse Path 1", 1486 | "mn": "ADBE Vector Shape - Ellipse", 1487 | "hd": false 1488 | }, 1489 | { 1490 | "ty": "fl", 1491 | "c": { 1492 | "a": 0, 1493 | "k": [ 1494 | 1, 1495 | 0.788235008717, 1496 | 0.188234999776, 1497 | 1 1498 | ], 1499 | "ix": 4 1500 | }, 1501 | "o": { 1502 | "a": 0, 1503 | "k": 100, 1504 | "ix": 5 1505 | }, 1506 | "r": 1, 1507 | "nm": "Fill 1", 1508 | "mn": "ADBE Vector Graphic - Fill", 1509 | "hd": false 1510 | }, 1511 | { 1512 | "ty": "tr", 1513 | "p": { 1514 | "a": 0, 1515 | "k": [ 1516 | 0, 1517 | 0 1518 | ], 1519 | "ix": 2 1520 | }, 1521 | "a": { 1522 | "a": 0, 1523 | "k": [ 1524 | 0, 1525 | 0 1526 | ], 1527 | "ix": 1 1528 | }, 1529 | "s": { 1530 | "a": 0, 1531 | "k": [ 1532 | 100, 1533 | 100 1534 | ], 1535 | "ix": 3 1536 | }, 1537 | "r": { 1538 | "a": 0, 1539 | "k": 0, 1540 | "ix": 6 1541 | }, 1542 | "o": { 1543 | "a": 0, 1544 | "k": 100, 1545 | "ix": 7 1546 | }, 1547 | "sk": { 1548 | "a": 0, 1549 | "k": 0, 1550 | "ix": 4 1551 | }, 1552 | "sa": { 1553 | "a": 0, 1554 | "k": 0, 1555 | "ix": 5 1556 | }, 1557 | "nm": "Transform" 1558 | } 1559 | ], 1560 | "nm": "sun", 1561 | "np": 2, 1562 | "cix": 2, 1563 | "ix": 1, 1564 | "mn": "ADBE Vector Group", 1565 | "hd": false 1566 | } 1567 | ], 1568 | "ip": 0, 1569 | "op": 180, 1570 | "st": 0, 1571 | "bm": 0 1572 | }, 1573 | { 1574 | "ddd": 0, 1575 | "ind": 5, 1576 | "ty": 4, 1577 | "nm": "bond", 1578 | "sr": 1, 1579 | "ks": { 1580 | "o": { 1581 | "a": 0, 1582 | "k": 100, 1583 | "ix": 11 1584 | }, 1585 | "r": { 1586 | "a": 0, 1587 | "k": 0, 1588 | "ix": 10 1589 | }, 1590 | "p": { 1591 | "a": 0, 1592 | "k": [ 1593 | 127, 1594 | 128, 1595 | 0 1596 | ], 1597 | "ix": 2 1598 | }, 1599 | "a": { 1600 | "a": 0, 1601 | "k": [ 1602 | 0, 1603 | 0, 1604 | 0 1605 | ], 1606 | "ix": 1 1607 | }, 1608 | "s": { 1609 | "a": 0, 1610 | "k": [ 1611 | 100, 1612 | 100, 1613 | 100 1614 | ], 1615 | "ix": 6 1616 | } 1617 | }, 1618 | "ao": 0, 1619 | "shapes": [ 1620 | { 1621 | "ty": "gr", 1622 | "it": [ 1623 | { 1624 | "ty": "rc", 1625 | "d": 1, 1626 | "s": { 1627 | "a": 0, 1628 | "k": [ 1629 | 256, 1630 | 256 1631 | ], 1632 | "ix": 2 1633 | }, 1634 | "p": { 1635 | "a": 0, 1636 | "k": [ 1637 | 0, 1638 | 0 1639 | ], 1640 | "ix": 3 1641 | }, 1642 | "r": { 1643 | "a": 0, 1644 | "k": 0, 1645 | "ix": 4 1646 | }, 1647 | "nm": "Rectangle Path 1", 1648 | "mn": "ADBE Vector Shape - Rect", 1649 | "hd": false 1650 | }, 1651 | { 1652 | "ty": "tr", 1653 | "p": { 1654 | "a": 0, 1655 | "k": [ 1656 | 0, 1657 | 0 1658 | ], 1659 | "ix": 2 1660 | }, 1661 | "a": { 1662 | "a": 0, 1663 | "k": [ 1664 | 0, 1665 | 0 1666 | ], 1667 | "ix": 1 1668 | }, 1669 | "s": { 1670 | "a": 0, 1671 | "k": [ 1672 | 100, 1673 | 100 1674 | ], 1675 | "ix": 3 1676 | }, 1677 | "r": { 1678 | "a": 0, 1679 | "k": 0, 1680 | "ix": 6 1681 | }, 1682 | "o": { 1683 | "a": 0, 1684 | "k": 100, 1685 | "ix": 7 1686 | }, 1687 | "sk": { 1688 | "a": 0, 1689 | "k": 0, 1690 | "ix": 4 1691 | }, 1692 | "sa": { 1693 | "a": 0, 1694 | "k": 0, 1695 | "ix": 5 1696 | }, 1697 | "nm": "Transform" 1698 | } 1699 | ], 1700 | "nm": "bond", 1701 | "np": 1, 1702 | "cix": 2, 1703 | "ix": 1, 1704 | "mn": "ADBE Vector Group", 1705 | "hd": false 1706 | } 1707 | ], 1708 | "ip": 0, 1709 | "op": 180, 1710 | "st": 0, 1711 | "bm": 0 1712 | } 1713 | ], 1714 | "markers": [] 1715 | } -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | #FFBB86FC 14 | #FF6200EE 15 | #FF3700B3 16 | #FF03DAC5 17 | #FF018786 18 | #FF000000 19 | #FFFFFFFF 20 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | MiniWeather 13 | Next 4 days/hourly 14 | %1$dᵒ 15 | Humidity %1$d%% 16 | Wind %1$d km/hr 17 | Current Weather 18 | 19 | Minimum temperature can be %1$d Degree 20 | Maximum temperature can be %1$d Degree 21 | At %1$s, it has %2$s. The temperature is %3$d degree 22 | Currently, it\'s %1$d degree. %2$s. The humidity is %3$d percent and wind speed is %4$d km/hr. 23 | On %1$s, it\'s %2$d degree. %3$s. 24 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 33 | 34 | 38 | 39 |