├── .github ├── ci-gradle.properties └── workflows │ └── Check.yaml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README-template.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── androiddevchallenge │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── androiddevchallenge │ │ │ ├── MainActivity.kt │ │ │ ├── data │ │ │ └── model │ │ │ │ └── Puppy.kt │ │ │ ├── features │ │ │ ├── onboarding │ │ │ │ └── OnboaringScreen.kt │ │ │ ├── puppylist │ │ │ │ └── PuppyListScreen.kt │ │ │ └── puppylistdetail │ │ │ │ └── PuppyListDetailScreen.kt │ │ │ ├── ui │ │ │ └── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── Shape.kt │ │ │ │ ├── Theme.kt │ │ │ │ └── Type.kt │ │ │ └── util │ │ │ └── Routes.kt │ └── res │ │ ├── drawable-mdpi │ │ ├── art_puppy.xml │ │ ├── ic_paw.xml │ │ └── ic_search.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── font │ │ ├── nunito_black.ttf │ │ ├── nunito_bold.ttf │ │ ├── nunito_light.ttf │ │ ├── nunito_regular.ttf │ │ └── nunito_semi_bold.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 │ │ ├── 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 ├── gradlew.bat ├── results ├── screenshot_1.png ├── screenshot_2.png ├── screenshot_3.png └── video.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-template.md: -------------------------------------------------------------------------------- 1 | # Put title of your app here 2 | 3 | 4 | 5 | ![Workflow result](https://github.com///workflows/Check/badge.svg) 6 | 7 | 8 | ## :scroll: Description 9 | 10 | 11 | 12 | ## :bulb: Motivation and Context 13 | 14 | 15 | 16 | 17 | ## :camera_flash: Screenshots 18 | 19 | 20 | 21 | ## License 22 | ``` 23 | Copyright 2020 The Android Open Source Project 24 | 25 | Licensed under the Apache License, Version 2.0 (the "License"); 26 | you may not use this file except in compliance with the License. 27 | You may obtain a copy of the License at 28 | 29 | https://www.apache.org/licenses/LICENSE-2.0 30 | 31 | Unless required by applicable law or agreed to in writing, software 32 | distributed under the License is distributed on an "AS IS" BASIS, 33 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 34 | See the License for the specific language governing permissions and 35 | limitations under the License. 36 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adopt Puppy 2 | 3 | ![Workflow result](https://github.com/okanaydin/Android-Compose-Challenge/workflows/Check/badge.svg) 4 | 5 | 6 | ## :scroll: Description 7 | - This submission is a first-week challenge of #AndroidDevChallenge: Compose that showing a puppy list for adoption. 8 | 9 | 10 | 11 | ## :bulb: Motivation and Context 12 | - Users can see an awesome puppy list for adoption and all UI elements are developed with Jetpack Compose. 13 | 14 | ## :camera_flash: Screenshots 15 | 16 | 17 | 18 | ## License 19 | ``` 20 | Copyright 2020 The Android Open Source Project 21 | 22 | Licensed under the Apache License, Version 2.0 (the "License"); 23 | you may not use this file except in compliance with the License. 24 | You may obtain a copy of the License at 25 | 26 | https://www.apache.org/licenses/LICENSE-2.0 27 | 28 | Unless required by applicable law or agreed to in writing, software 29 | distributed under the License is distributed on an "AS IS" BASIS, 30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | See the License for the specific language governing permissions and 32 | limitations under the License. 33 | ``` 34 | -------------------------------------------------------------------------------- /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.2.0' 69 | implementation 'com.google.android.material:material:1.3.0' 70 | implementation "androidx.activity:activity-compose:1.3.0-alpha03" 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 | implementation "dev.chrisbanes.accompanist:accompanist-coil:0.6.0" 78 | implementation "androidx.navigation:navigation-compose:1.0.0-alpha08" 79 | testImplementation 'junit:junit:4.13.2' 80 | 81 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 82 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" 83 | } -------------------------------------------------------------------------------- /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/androidTest/java/com/example/androiddevchallenge/ExampleInstrumentedTest.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 androidx.compose.ui.test.junit4.createAndroidComposeRule 19 | import androidx.test.ext.junit.runners.AndroidJUnit4 20 | import org.junit.Rule 21 | import org.junit.Test 22 | import org.junit.runner.RunWith 23 | 24 | /** 25 | * Instrumented test, which will execute on an Android device. 26 | * 27 | * See [testing documentation](http://d.android.com/tools/testing). 28 | */ 29 | @RunWith(AndroidJUnit4::class) 30 | class ExampleInstrumentedTest { 31 | @get:Rule 32 | val composeTestRule = createAndroidComposeRule() 33 | 34 | @Test 35 | fun sampleTest() { 36 | // Add instrumented tests here 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | 16 | 17 | 18 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /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 androidx.compose.runtime.Composable 22 | import androidx.compose.ui.tooling.preview.Preview 23 | import androidx.navigation.NavType 24 | import androidx.navigation.compose.NavHost 25 | import androidx.navigation.compose.composable 26 | import androidx.navigation.compose.navArgument 27 | import androidx.navigation.compose.rememberNavController 28 | import com.example.androiddevchallenge.features.onboarding.OnboardingScreen 29 | import com.example.androiddevchallenge.features.puppylist.PuppyListScreen 30 | import com.example.androiddevchallenge.features.puppylistdetail.PuppyListDetailScreen 31 | import com.example.androiddevchallenge.ui.theme.MyTheme 32 | import com.example.androiddevchallenge.util.Routes 33 | import com.example.androiddevchallenge.util.Routes.PUPPY_LIST_DETAIL_ARGUMENT 34 | import com.example.androiddevchallenge.util.Routes.PUPPY_LIST_DETAIL_SCREEN 35 | 36 | class MainActivity : AppCompatActivity() { 37 | override fun onCreate(savedInstanceState: Bundle?) { 38 | super.onCreate(savedInstanceState) 39 | setContent { 40 | MyTheme { 41 | MyApp() 42 | } 43 | } 44 | } 45 | } 46 | 47 | // Start building your app here! 48 | @Composable 49 | fun MyApp() { 50 | val navController = rememberNavController() 51 | 52 | NavHost(navController = navController, startDestination = Routes.ONBOARDING_SCREEN) { 53 | 54 | composable(Routes.ONBOARDING_SCREEN) { 55 | OnboardingScreen(navController = navController) 56 | } 57 | 58 | composable(Routes.PUPPY_LIST_SCREEN) { 59 | PuppyListScreen(navController = navController) 60 | } 61 | 62 | composable( 63 | route = PUPPY_LIST_DETAIL_SCREEN, 64 | arguments = listOf(navArgument(PUPPY_LIST_DETAIL_ARGUMENT) { type = NavType.IntType }) 65 | ) { 66 | it.arguments?.getInt(PUPPY_LIST_DETAIL_ARGUMENT)?.let { puppyID -> 67 | PuppyListDetailScreen( 68 | navController, 69 | puppyID 70 | ) 71 | } 72 | } 73 | } 74 | } 75 | 76 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 77 | @Composable 78 | fun LightPreview() { 79 | MyTheme { 80 | MyApp() 81 | } 82 | } 83 | 84 | @Preview("Dark Theme", widthDp = 360, heightDp = 640) 85 | @Composable 86 | fun DarkPreview() { 87 | MyTheme(darkTheme = true) { 88 | MyApp() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/data/model/Puppy.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.data.model 17 | 18 | data class Puppy( 19 | val id: Int, 20 | val name: String, 21 | val breed: String, 22 | val age: Int, 23 | val image: String, 24 | val color: String, 25 | val sex: String, 26 | val weight: String, 27 | ) 28 | 29 | val images = listOf( 30 | "https://images.unsplash.com/photo-1517423440428-a5a00ad493e8?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=687&q=80", 31 | "https://images.unsplash.com/photo-1583512603805-3cc6b41f3edb?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=800&q=80", 32 | "https://images.unsplash.com/photo-1583511655857-d19b40a7a54e?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1049&q=80", 33 | "https://images.unsplash.com/photo-1517423568366-8b83523034fd?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=675&q=80", 34 | "https://images.unsplash.com/photo-1517849845537-4d257902454a?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=675&q=80", 35 | "https://images.unsplash.com/photo-1585559700398-1385b3a8aeb6?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80", 36 | "https://images.unsplash.com/photo-1558788353-f76d92427f16?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=678&q=80", 37 | "https://images.unsplash.com/photo-1537151672256-6caf2e9f8c95?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=633&q=80", 38 | "https://images.unsplash.com/photo-1588269845464-8993565cac3a?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=634&q=80", 39 | "https://images.unsplash.com/photo-1530041539828-114de669390e?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=634&q=80" 40 | ) 41 | 42 | val puppyList = listOf( 43 | Puppy(1001, "Carmen", "Barbet", 1, images[0], "White", "Male", "2KG"), 44 | Puppy(1002, "Lola", "Terrier", 2, images[1], "Black", "Male", "2KG"), 45 | Puppy(1003, "Coco", "Boxer", 1, images[2], "White", "Male", "2KG"), 46 | Puppy(1004, "Wand", "Pug", 2, images[3], "White", "Male", "2KG"), 47 | Puppy(1005, "Nugget", "Drev", 2, images[4], "Black", "Female", "2KG"), 48 | Puppy(1006, "Sugar", "Chug", 1, images[5], "White", "Male", "2KG"), 49 | Puppy(1007, "Charlie", "Dorgi", 1, images[6], "White", "Male", "2KG"), 50 | Puppy(1008, "Max", "Golden", 1, images[7], "Black", "Male", "2KG"), 51 | Puppy(1009, "Buddy", "Morkie", 2, images[8], "White", "Male", "2KG"), 52 | Puppy(1010, "Teddy", "Pug", 1, images[9], "White", "Male", "2KG") 53 | ) 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/features/onboarding/OnboaringScreen.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.features.onboarding 17 | 18 | import android.os.Handler 19 | import android.os.Looper 20 | import androidx.compose.foundation.Image 21 | import androidx.compose.foundation.background 22 | import androidx.compose.foundation.layout.Column 23 | import androidx.compose.foundation.layout.Spacer 24 | import androidx.compose.foundation.layout.fillMaxHeight 25 | import androidx.compose.foundation.layout.fillMaxWidth 26 | import androidx.compose.foundation.layout.padding 27 | import androidx.compose.foundation.layout.requiredHeight 28 | import androidx.compose.material.LocalTextStyle 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.layout.ContentScale 34 | import androidx.compose.ui.res.colorResource 35 | import androidx.compose.ui.res.painterResource 36 | import androidx.compose.ui.res.stringResource 37 | import androidx.compose.ui.text.font.Font 38 | import androidx.compose.ui.text.font.FontFamily 39 | import androidx.compose.ui.tooling.preview.Preview 40 | import androidx.compose.ui.unit.dp 41 | import androidx.compose.ui.unit.sp 42 | import androidx.navigation.NavController 43 | import androidx.navigation.compose.navigate 44 | import androidx.navigation.compose.rememberNavController 45 | import com.example.androiddevchallenge.R 46 | import com.example.androiddevchallenge.ui.theme.MyTheme 47 | import com.example.androiddevchallenge.util.Routes 48 | 49 | @Composable 50 | fun OnboardingScreen( 51 | navController: NavController 52 | ) { 53 | OnboardingUI(navController = navController) 54 | } 55 | 56 | @Composable 57 | fun OnboardingUI(navController: NavController) { 58 | 59 | Column( 60 | horizontalAlignment = Alignment.CenterHorizontally, 61 | modifier = Modifier 62 | .fillMaxWidth() 63 | .fillMaxHeight() 64 | .background(colorResource(id = R.color.orange)) 65 | .padding(24.dp) 66 | ) { 67 | 68 | Spacer(Modifier.requiredHeight(60.dp)) 69 | 70 | Image( 71 | painter = painterResource(R.drawable.art_puppy), 72 | contentDescription = null, 73 | modifier = Modifier.fillMaxWidth(), 74 | contentScale = ContentScale.FillWidth, 75 | alignment = Alignment.Center 76 | ) 77 | 78 | Spacer(Modifier.requiredHeight(16.dp)) 79 | 80 | Text( 81 | text = stringResource(R.string.adopt_puppy), 82 | color = colorResource(id = R.color.dark_grey), 83 | style = LocalTextStyle.current.copy( 84 | fontSize = 32.sp, 85 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 86 | ) 87 | ) 88 | 89 | Handler(Looper.getMainLooper()).postDelayed( 90 | { 91 | navController.navigate(Routes.PUPPY_LIST_SCREEN) 92 | }, 93 | 2000 94 | ) 95 | } 96 | } 97 | 98 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 99 | @Composable 100 | fun LightPreview() { 101 | MyTheme { 102 | OnboardingScreen(navController = rememberNavController()) 103 | } 104 | } 105 | 106 | @Preview("Dark Theme", widthDp = 360, heightDp = 640) 107 | @Composable 108 | fun DarkPreview() { 109 | MyTheme(darkTheme = true) { 110 | OnboardingScreen(navController = rememberNavController()) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/features/puppylist/PuppyListScreen.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.features.puppylist 17 | 18 | import androidx.compose.foundation.Image 19 | import androidx.compose.foundation.background 20 | import androidx.compose.foundation.clickable 21 | import androidx.compose.foundation.layout.Arrangement 22 | import androidx.compose.foundation.layout.Column 23 | import androidx.compose.foundation.layout.Row 24 | import androidx.compose.foundation.layout.Spacer 25 | import androidx.compose.foundation.layout.fillMaxHeight 26 | import androidx.compose.foundation.layout.fillMaxWidth 27 | import androidx.compose.foundation.layout.height 28 | import androidx.compose.foundation.layout.padding 29 | import androidx.compose.foundation.layout.requiredHeight 30 | import androidx.compose.foundation.layout.width 31 | import androidx.compose.foundation.lazy.LazyColumn 32 | import androidx.compose.foundation.lazy.LazyRow 33 | import androidx.compose.foundation.lazy.items 34 | import androidx.compose.foundation.lazy.itemsIndexed 35 | import androidx.compose.foundation.shape.RoundedCornerShape 36 | import androidx.compose.material.Card 37 | import androidx.compose.material.LocalTextStyle 38 | import androidx.compose.material.MaterialTheme 39 | import androidx.compose.material.Surface 40 | import androidx.compose.material.Text 41 | import androidx.compose.runtime.Composable 42 | import androidx.compose.ui.Alignment 43 | import androidx.compose.ui.Modifier 44 | import androidx.compose.ui.layout.ContentScale 45 | import androidx.compose.ui.res.colorResource 46 | import androidx.compose.ui.res.painterResource 47 | import androidx.compose.ui.res.stringResource 48 | import androidx.compose.ui.text.font.Font 49 | import androidx.compose.ui.text.font.FontFamily 50 | import androidx.compose.ui.text.style.TextAlign 51 | import androidx.compose.ui.tooling.preview.Preview 52 | import androidx.compose.ui.unit.dp 53 | import androidx.compose.ui.unit.sp 54 | import androidx.navigation.NavController 55 | import androidx.navigation.compose.navigate 56 | import androidx.navigation.compose.rememberNavController 57 | import com.example.androiddevchallenge.R 58 | import com.example.androiddevchallenge.data.model.Puppy 59 | import com.example.androiddevchallenge.data.model.puppyList 60 | import com.example.androiddevchallenge.ui.theme.MyTheme 61 | import com.example.androiddevchallenge.util.Routes 62 | import dev.chrisbanes.accompanist.coil.CoilImage 63 | import dev.chrisbanes.accompanist.imageloading.ImageLoadState 64 | import dev.chrisbanes.accompanist.imageloading.MaterialLoadingImage 65 | 66 | @Composable 67 | fun PuppyListScreen( 68 | navController: NavController 69 | ) { 70 | 71 | MaterialTheme { 72 | Column( 73 | horizontalAlignment = Alignment.Start, 74 | modifier = Modifier 75 | .fillMaxWidth() 76 | .background(colorResource(id = R.color.white_100)) 77 | .padding(start = 24.dp, top = 16.dp, end = 24.dp) 78 | ) { 79 | Row { 80 | Text( 81 | text = stringResource(id = R.string.adopt_puppy), 82 | color = colorResource(id = R.color.dark_grey), 83 | style = LocalTextStyle.current.copy( 84 | fontSize = 32.sp, 85 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 86 | ) 87 | ) 88 | Image( 89 | modifier = Modifier 90 | .fillMaxWidth() 91 | .height(40.dp), 92 | contentDescription = null, 93 | alignment = Alignment.CenterEnd, 94 | painter = painterResource(R.drawable.art_puppy), 95 | ) 96 | } 97 | 98 | Text( 99 | text = stringResource(R.string.your_favourite_soulmate_pet), 100 | color = colorResource(id = R.color.grey_200), 101 | style = LocalTextStyle.current.copy( 102 | fontSize = 16.sp, 103 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)) 104 | ) 105 | ) 106 | 107 | Card( 108 | backgroundColor = colorResource(id = R.color.white), 109 | elevation = 1.dp, shape = RoundedCornerShape(16.dp), 110 | modifier = Modifier 111 | .fillMaxWidth() 112 | .padding(top = 24.dp) 113 | ) { 114 | Row { 115 | Text( 116 | text = stringResource(R.string.search_your_soulmate_pet), 117 | color = colorResource(id = R.color.grey_200), 118 | modifier = Modifier.padding(16.dp), 119 | style = LocalTextStyle.current.copy( 120 | fontSize = 12.sp, 121 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 122 | textAlign = TextAlign.Center 123 | ) 124 | ) 125 | Image( 126 | modifier = Modifier 127 | .fillMaxWidth() 128 | .padding(8.dp), 129 | painter = painterResource(id = R.drawable.ic_search), 130 | contentDescription = null, 131 | alignment = Alignment.CenterEnd 132 | ) 133 | } 134 | } 135 | 136 | Spacer(modifier = Modifier.requiredHeight(16.dp)) 137 | 138 | Surface(color = colorResource(id = R.color.white_100)) { 139 | LazyRow { 140 | items(puppyList) { puppy -> 141 | PuppyListFilter(puppy) 142 | } 143 | } 144 | } 145 | 146 | Spacer(modifier = Modifier.requiredHeight(8.dp)) 147 | 148 | PuppyList( 149 | onItemClicked = { currentPuppy -> 150 | navController.navigate(Routes.createPuppyListDetailDirection(puppyList[currentPuppy])) 151 | } 152 | ) 153 | } 154 | } 155 | } 156 | 157 | @Composable 158 | fun PuppyList(onItemClicked: (index: Int) -> Unit) { 159 | Surface(color = colorResource(id = R.color.white_100)) { 160 | LazyColumn( 161 | modifier = Modifier 162 | .padding(bottom = 16.dp) 163 | .clickable { onItemClicked } 164 | ) { 165 | itemsIndexed(puppyList) { index, puppy -> 166 | PuppyListItem(puppy, index, onItemClicked) 167 | } 168 | } 169 | } 170 | } 171 | 172 | @Composable 173 | fun PuppyListItem(puppy: Puppy, index: Int, onItemClicked: (index: Int) -> Unit) { 174 | Card( 175 | backgroundColor = colorResource(id = R.color.white), 176 | shape = RoundedCornerShape(16.dp), 177 | modifier = Modifier.padding( 178 | top = 16.dp, start = 2.dp, end = 2.dp 179 | ) 180 | ) { 181 | 182 | Row( 183 | verticalAlignment = Alignment.CenterVertically, 184 | modifier = Modifier 185 | .fillMaxWidth() 186 | .clickable(onClick = { onItemClicked(index) }) 187 | ) { 188 | 189 | CoilImage(data = puppy.image) { imageState -> 190 | when (imageState) { 191 | is ImageLoadState.Success -> { 192 | Card( 193 | modifier = Modifier.padding(8.dp), 194 | shape = RoundedCornerShape(46.dp) 195 | ) { 196 | MaterialLoadingImage( 197 | result = imageState, 198 | contentDescription = null, 199 | fadeInEnabled = true, 200 | fadeInDurationMs = 600, 201 | modifier = Modifier 202 | .height(96.dp) 203 | .width(96.dp), 204 | contentScale = ContentScale.FillBounds, 205 | skipFadeWhenLoadedFromMemory = true 206 | ) 207 | } 208 | } 209 | is ImageLoadState.Error -> Text(text = "Error") 210 | is ImageLoadState.Loading -> Text(text = "Loading") 211 | is ImageLoadState.Empty -> Text(text = "Empty") 212 | } 213 | } 214 | 215 | Column( 216 | horizontalAlignment = Alignment.Start, 217 | modifier = Modifier 218 | .fillMaxWidth() 219 | .padding(top = 8.dp, bottom = 8.dp) 220 | ) { 221 | Text( 222 | text = puppy.name, 223 | modifier = Modifier.padding(start = 6.dp), 224 | style = LocalTextStyle.current.copy( 225 | color = colorResource(id = R.color.grey_700), 226 | fontSize = 20.sp, 227 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)) 228 | ) 229 | ) 230 | 231 | Row( 232 | modifier = Modifier 233 | .height(24.dp) 234 | .padding(top = 8.dp) 235 | ) { 236 | 237 | Image( 238 | painter = painterResource(R.drawable.art_puppy), 239 | contentDescription = null, 240 | modifier = Modifier 241 | .width(20.dp) 242 | .height(20.dp) 243 | .padding(start = 6.dp) 244 | ) 245 | 246 | Text( 247 | text = puppy.breed, 248 | modifier = Modifier 249 | .padding(start = 4.dp) 250 | .height(24.dp), 251 | style = LocalTextStyle.current.copy( 252 | fontSize = 12.sp, 253 | color = colorResource(id = R.color.grey_200), 254 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 255 | textAlign = TextAlign.Center 256 | ) 257 | ) 258 | } 259 | 260 | Spacer(Modifier.requiredHeight(12.dp)) 261 | 262 | Row { 263 | Card( 264 | shape = RoundedCornerShape(8.dp), 265 | backgroundColor = colorResource(id = R.color.red), 266 | modifier = Modifier 267 | .padding(6.dp) 268 | .width(50.dp) 269 | .height(24.dp) 270 | ) { 271 | Text( 272 | text = puppy.color, 273 | modifier = Modifier 274 | .fillMaxHeight() 275 | .fillMaxWidth() 276 | .padding(4.dp), 277 | style = LocalTextStyle.current.copy( 278 | fontSize = 12.sp, 279 | color = colorResource(id = R.color.white), 280 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 281 | textAlign = TextAlign.Center 282 | ) 283 | ) 284 | } 285 | 286 | Card( 287 | shape = RoundedCornerShape(8.dp), 288 | backgroundColor = colorResource(id = R.color.cyan), 289 | modifier = Modifier 290 | .padding(6.dp) 291 | .width(50.dp) 292 | .height(24.dp) 293 | ) { 294 | Text( 295 | text = puppy.sex, 296 | modifier = Modifier 297 | .fillMaxHeight() 298 | .fillMaxWidth() 299 | .padding(4.dp), 300 | style = LocalTextStyle.current.copy( 301 | fontSize = 12.sp, 302 | color = colorResource(id = R.color.white), 303 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 304 | textAlign = TextAlign.Center 305 | ) 306 | ) 307 | } 308 | 309 | Card( 310 | shape = RoundedCornerShape(8.dp), 311 | backgroundColor = colorResource(id = R.color.yellow), 312 | modifier = Modifier 313 | .padding(6.dp) 314 | .width(50.dp) 315 | .height(24.dp) 316 | ) { 317 | Text( 318 | text = "${puppy.age} year", 319 | modifier = Modifier 320 | .fillMaxHeight() 321 | .fillMaxWidth() 322 | .padding(4.dp), 323 | style = LocalTextStyle.current.copy( 324 | fontSize = 12.sp, 325 | color = colorResource(id = R.color.white), 326 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 327 | textAlign = TextAlign.Center 328 | ) 329 | ) 330 | } 331 | } 332 | } 333 | } 334 | } 335 | } 336 | 337 | @Composable 338 | fun PuppyListFilter(puppy: Puppy) { 339 | Card( 340 | backgroundColor = colorResource(id = R.color.white), 341 | shape = RoundedCornerShape(16.dp), 342 | modifier = Modifier 343 | .padding(start = 4.dp, top = 2.dp, end = 4.dp, bottom = 2.dp) 344 | .width(75.dp) 345 | .height(30.dp), 346 | ) { 347 | Row( 348 | horizontalArrangement = Arrangement.Center, 349 | verticalAlignment = Alignment.CenterVertically 350 | ) { 351 | 352 | CoilImage(data = puppy.image) { imageState -> 353 | when (imageState) { 354 | is ImageLoadState.Success -> { 355 | Card( 356 | shape = RoundedCornerShape(10.dp) 357 | ) { 358 | MaterialLoadingImage( 359 | result = imageState, 360 | contentDescription = null, 361 | fadeInEnabled = true, 362 | fadeInDurationMs = 600, 363 | modifier = Modifier 364 | .width(20.dp) 365 | .height(20.dp), 366 | contentScale = ContentScale.FillBounds, 367 | skipFadeWhenLoadedFromMemory = true 368 | ) 369 | } 370 | } 371 | is ImageLoadState.Error -> Text(text = "Error") 372 | is ImageLoadState.Loading -> Text(text = "Loading") 373 | is ImageLoadState.Empty -> Text(text = "Empty") 374 | } 375 | } 376 | 377 | Text( 378 | text = puppy.breed, 379 | modifier = Modifier.padding(start = 4.dp), 380 | style = LocalTextStyle.current.copy( 381 | fontSize = 12.sp, 382 | color = colorResource(id = R.color.grey_200), 383 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)), 384 | textAlign = TextAlign.Center, 385 | ) 386 | ) 387 | } 388 | } 389 | } 390 | 391 | @Preview("Light Theme", widthDp = 360, heightDp = 640) 392 | @Composable 393 | fun LightPreview() { 394 | MyTheme { 395 | PuppyListScreen(navController = rememberNavController()) 396 | } 397 | } 398 | 399 | @Preview("Dark Theme", widthDp = 360, heightDp = 640) 400 | @Composable 401 | fun DarkPreview() { 402 | MyTheme(darkTheme = true) { 403 | PuppyListScreen(navController = rememberNavController()) 404 | } 405 | } 406 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/features/puppylistdetail/PuppyListDetailScreen.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.features.puppylistdetail 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.fillMaxHeight 23 | import androidx.compose.foundation.layout.fillMaxWidth 24 | import androidx.compose.foundation.layout.height 25 | import androidx.compose.foundation.layout.padding 26 | import androidx.compose.foundation.layout.requiredHeight 27 | import androidx.compose.foundation.layout.width 28 | import androidx.compose.foundation.shape.RoundedCornerShape 29 | import androidx.compose.material.Card 30 | import androidx.compose.material.LocalTextStyle 31 | import androidx.compose.material.Text 32 | import androidx.compose.runtime.Composable 33 | import androidx.compose.ui.Alignment 34 | import androidx.compose.ui.Modifier 35 | import androidx.compose.ui.layout.ContentScale 36 | import androidx.compose.ui.res.colorResource 37 | import androidx.compose.ui.res.stringResource 38 | import androidx.compose.ui.text.font.Font 39 | import androidx.compose.ui.text.font.FontFamily 40 | import androidx.compose.ui.text.style.TextAlign 41 | import androidx.compose.ui.unit.dp 42 | import androidx.compose.ui.unit.sp 43 | import androidx.navigation.NavController 44 | import com.example.androiddevchallenge.R 45 | import com.example.androiddevchallenge.data.model.puppyList 46 | import dev.chrisbanes.accompanist.coil.CoilImage 47 | import dev.chrisbanes.accompanist.imageloading.ImageLoadState 48 | import dev.chrisbanes.accompanist.imageloading.MaterialLoadingImage 49 | 50 | @Composable 51 | fun PuppyListDetailScreen( 52 | navController: NavController, 53 | puppyID: Int 54 | ) { 55 | 56 | val puppy = puppyList.find { puppy -> puppy.id == puppyID } 57 | 58 | Column { 59 | 60 | CoilImage( 61 | data = puppy!!.image, 62 | ) { imageState -> 63 | when (imageState) { 64 | is ImageLoadState.Success -> { 65 | Card( 66 | shape = RoundedCornerShape(bottomEnd = 20.dp, bottomStart = 20.dp) 67 | ) { 68 | MaterialLoadingImage( 69 | result = imageState, 70 | contentDescription = null, 71 | fadeInEnabled = true, 72 | fadeInDurationMs = 600, 73 | modifier = Modifier.height(360.dp), 74 | alignment = Alignment.Center, 75 | contentScale = ContentScale.FillBounds, 76 | skipFadeWhenLoadedFromMemory = true 77 | ) 78 | } 79 | } 80 | is ImageLoadState.Error -> Text(text = "Error") 81 | is ImageLoadState.Loading -> Text(text = "Loading") 82 | is ImageLoadState.Empty -> Text(text = "Empty") 83 | } 84 | } 85 | 86 | Row( 87 | modifier = Modifier.fillMaxWidth(), 88 | horizontalArrangement = Arrangement.Center 89 | ) { 90 | Card( 91 | modifier = Modifier.padding(start = 8.dp, top = 8.dp), 92 | shape = RoundedCornerShape(6.dp) 93 | ) { 94 | Column( 95 | horizontalAlignment = Alignment.CenterHorizontally, 96 | modifier = Modifier 97 | .width(60.dp) 98 | .height(50.dp) 99 | .padding(top = 8.dp, bottom = 8.dp) 100 | ) { 101 | Text( 102 | text = stringResource(R.string.age), 103 | style = LocalTextStyle.current.copy( 104 | fontSize = 14.sp, 105 | color = colorResource(id = R.color.grey_700), 106 | fontFamily = FontFamily(Font(resId = R.font.nunito_light)) 107 | ) 108 | ) 109 | Text( 110 | text = puppy.age.toString(), 111 | style = LocalTextStyle.current.copy( 112 | fontSize = 14.sp, 113 | color = colorResource(id = R.color.grey_700), 114 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 115 | ) 116 | ) 117 | } 118 | } 119 | 120 | Card( 121 | modifier = Modifier.padding(start = 8.dp, top = 8.dp), 122 | shape = RoundedCornerShape(6.dp) 123 | ) { 124 | Column( 125 | horizontalAlignment = Alignment.CenterHorizontally, 126 | modifier = Modifier 127 | .width(60.dp) 128 | .height(50.dp) 129 | .padding(top = 8.dp, bottom = 8.dp) 130 | ) { 131 | Text( 132 | text = stringResource(R.string.color), 133 | style = LocalTextStyle.current.copy( 134 | fontSize = 14.sp, 135 | color = colorResource(id = R.color.grey_700), 136 | fontFamily = FontFamily(Font(resId = R.font.nunito_light)) 137 | ) 138 | ) 139 | Text( 140 | text = puppy.color, 141 | style = LocalTextStyle.current.copy( 142 | fontSize = 14.sp, 143 | color = colorResource(id = R.color.grey_700), 144 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 145 | ) 146 | ) 147 | } 148 | } 149 | 150 | Card( 151 | modifier = Modifier.padding(start = 8.dp, top = 8.dp), 152 | shape = RoundedCornerShape(6.dp) 153 | ) { 154 | Column( 155 | modifier = Modifier 156 | .width(60.dp) 157 | .height(50.dp) 158 | .padding(top = 8.dp, bottom = 8.dp), 159 | horizontalAlignment = Alignment.CenterHorizontally 160 | ) { 161 | Text( 162 | text = stringResource(R.string.sex), 163 | style = LocalTextStyle.current.copy( 164 | fontSize = 14.sp, 165 | color = colorResource(id = R.color.grey_700), 166 | fontFamily = FontFamily(Font(resId = R.font.nunito_light)) 167 | ) 168 | ) 169 | 170 | Text( 171 | text = puppy.sex, 172 | style = LocalTextStyle.current.copy( 173 | fontSize = 14.sp, 174 | color = colorResource(id = R.color.grey_700), 175 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 176 | ) 177 | ) 178 | } 179 | } 180 | 181 | Card( 182 | modifier = Modifier.padding(start = 8.dp, top = 8.dp), 183 | shape = RoundedCornerShape(6.dp) 184 | ) { 185 | Column( 186 | horizontalAlignment = Alignment.CenterHorizontally, 187 | modifier = Modifier 188 | .width(60.dp) 189 | .height(50.dp) 190 | .padding(top = 8.dp, bottom = 8.dp) 191 | ) { 192 | Text( 193 | text = stringResource(R.string.weight), 194 | style = LocalTextStyle.current.copy( 195 | fontSize = 14.sp, 196 | color = colorResource(id = R.color.grey_700), 197 | fontFamily = FontFamily(Font(resId = R.font.nunito_light)) 198 | ) 199 | ) 200 | Text( 201 | text = puppy.weight, 202 | style = LocalTextStyle.current.copy( 203 | fontSize = 14.sp, 204 | color = colorResource(id = R.color.grey_700), 205 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)) 206 | ) 207 | ) 208 | } 209 | } 210 | } 211 | 212 | Text( 213 | text = puppy.name, 214 | modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp), 215 | style = LocalTextStyle.current.copy( 216 | fontSize = 24.sp, 217 | color = colorResource(id = R.color.dark_grey), 218 | fontFamily = FontFamily(Font(resId = R.font.nunito_semi_bold)) 219 | ) 220 | ) 221 | 222 | Text( 223 | text = stringResource(R.string.lorem_text), 224 | modifier = Modifier.padding(start = 16.dp, top = 16.dp, end = 16.dp), 225 | style = LocalTextStyle.current.copy( 226 | fontSize = 14.sp, 227 | color = colorResource(id = R.color.grey_700), 228 | fontFamily = FontFamily(Font(resId = R.font.nunito_regular)) 229 | ) 230 | ) 231 | 232 | Spacer(Modifier.requiredHeight(24.dp)) 233 | 234 | Card( 235 | shape = RoundedCornerShape(20.dp), 236 | backgroundColor = colorResource(id = R.color.orange), 237 | modifier = Modifier 238 | .fillMaxWidth() 239 | .height(56.dp) 240 | .padding(start = 24.dp, end = 24.dp) 241 | ) { 242 | Text( 243 | text = stringResource(R.string.adopt_now), 244 | modifier = Modifier 245 | .fillMaxWidth() 246 | .fillMaxHeight() 247 | .padding(top = 16.dp), 248 | style = LocalTextStyle.current.copy( 249 | fontSize = 18.sp, 250 | color = colorResource(id = R.color.white_100), 251 | fontFamily = FontFamily(Font(resId = R.font.nunito_bold)), 252 | textAlign = TextAlign.Center 253 | ) 254 | ) 255 | } 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /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 purple200 = Color(0xFFBB86FC) 21 | val purple500 = Color(0xFF6200EE) 22 | val purple700 = Color(0xFF3700B3) 23 | val teal200 = Color(0xFF03DAC5) 24 | -------------------------------------------------------------------------------- /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(4.dp), 25 | large = RoundedCornerShape(0.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 | 24 | private val DarkColorPalette = darkColors( 25 | primary = purple200, 26 | primaryVariant = purple700, 27 | secondary = teal200 28 | ) 29 | 30 | private val LightColorPalette = lightColors( 31 | primary = purple500, 32 | primaryVariant = purple700, 33 | secondary = teal200 34 | 35 | /* Other default colors to override 36 | background = Color.White, 37 | surface = Color.White, 38 | onPrimary = Color.White, 39 | onSecondary = Color.Black, 40 | onBackground = Color.Black, 41 | onSurface = Color.Black, 42 | */ 43 | ) 44 | 45 | @Composable 46 | fun MyTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { 47 | val colors = if (darkTheme) { 48 | DarkColorPalette 49 | } else { 50 | LightColorPalette 51 | } 52 | 53 | MaterialTheme( 54 | colors = colors, 55 | typography = typography, 56 | shapes = shapes, 57 | content = content 58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /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.FontFamily 21 | import androidx.compose.ui.text.font.FontWeight 22 | import androidx.compose.ui.unit.sp 23 | 24 | // Set of Material typography styles to start with 25 | val typography = Typography( 26 | body1 = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Normal, 29 | fontSize = 16.sp 30 | ) 31 | /* Other default text styles to override 32 | button = TextStyle( 33 | fontFamily = FontFamily.Default, 34 | fontWeight = FontWeight.W500, 35 | fontSize = 14.sp 36 | ), 37 | caption = TextStyle( 38 | fontFamily = FontFamily.Default, 39 | fontWeight = FontWeight.Normal, 40 | fontSize = 12.sp 41 | ) 42 | */ 43 | ) 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androiddevchallenge/util/Routes.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.data.model.Puppy 19 | 20 | object Routes { 21 | 22 | const val ONBOARDING_SCREEN = "onboarding" 23 | const val PUPPY_LIST_SCREEN = "puppy_list" 24 | const val PUPPY_LIST_DETAIL_ARGUMENT = "puppy_ID" 25 | const val PUPPY_LIST_DETAIL_SCREEN = "puppy_list_detail/{$PUPPY_LIST_DETAIL_ARGUMENT}" 26 | 27 | fun createPuppyListDetailDirection(puppy: Puppy) = "puppy_list_detail/${puppy.id}" 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/art_puppy.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | 42 | 45 | 48 | 51 | 54 | 57 | 60 | 63 | 66 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 99 | 102 | 105 | 108 | 111 | 114 | 117 | 120 | 123 | 126 | 129 | 132 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 162 | 165 | 168 | 171 | 174 | 177 | 180 | 183 | 186 | 189 | 192 | 195 | 198 | 201 | 204 | 207 | 210 | 213 | 216 | 219 | 222 | 225 | 228 | 231 | 234 | 237 | 240 | 243 | 246 | 249 | 252 | 255 | 258 | 261 | 264 | 267 | 270 | 273 | 276 | 279 | 282 | 285 | 288 | 291 | 294 | 297 | 300 | 303 | 306 | 309 | 312 | 315 | 318 | 321 | 324 | 325 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_paw.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_search.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /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_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/nunito_black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/font/nunito_black.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/nunito_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/font/nunito_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/nunito_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/font/nunito_light.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/nunito_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/font/nunito_regular.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/nunito_semi_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/font/nunito_semi_bold.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/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okanaydin/Android-Compose-Challenge/b725cbcb05d207f1ee97fa02d8ce6aca3f0b547f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | #FFBB86FC 13 | #FF8D5C 14 | #FF8D5C 15 | #FF03DAC5 16 | #FF018786 17 | #FF000000 18 | #FFFFFFFF 19 | #F6F6F6 20 | #00A0E7 21 | #EEEDEF 22 | #ACACAC 23 | #494849 24 | #24202A 25 | #FF8D5C 26 | #FF5858 27 | #23F3DF 28 | #FFDE5A 29 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | AndroidDevChallenge 13 | Explore Now 14 | Adopt Now 15 | Adopt Puppy 16 | your favourite soulmate pet 17 | Age 18 | Color 19 | Sex 20 | Weight 21 | Lorem ipsum is a name for a common type of placeholder text. Also known as filler or dummy text, this is simply copy that serves to fill a space without actually saying anything meaningful. ... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua 22 | Search your soulmate pet 23 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 26 | 27 | 31 | 32 |