├── .editorconfig ├── .github ├── .java-version ├── actions │ └── workflow_setup │ │ └── action.yml ├── pull_request_template.md └── workflows │ ├── android_build.yml │ ├── android_ui_tests.yml │ ├── danger_checks.yml │ ├── install_git_hooks_macos.yml │ ├── install_git_hooks_windows.yml │ └── template_change_test.yml ├── .gitignore ├── Dangerfile.df.kts ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── template │ │ ├── MainActivity.kt │ │ ├── TemplateApp.kt │ │ └── theme │ │ ├── Color.kt │ │ ├── Shape.kt │ │ ├── Theme.kt │ │ └── Type.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── values-night │ └── themes.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle.kts ├── buildscripts ├── githooks.gradle ├── setup.gradle └── versionsplugin.gradle ├── config └── detekt │ └── detekt.yml ├── documentation ├── GitHooks.md ├── GitHubActions.md ├── StaticAnalysis.md └── VersionsPlugin.md ├── git-hooks ├── pre-commit-macos.sh ├── pre-commit-windows.sh ├── pre-push-macos.sh └── pre-push-windows.sh ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── renovate.json5 └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{kt,kts}] 4 | max_line_length = 140 5 | indent_size = 4 6 | insert_final_newline = true 7 | ij_kotlin_allow_trailing_comma = true 8 | ij_kotlin_allow_trailing_comma_on_call_site = true 9 | ktlint_function_naming_ignore_when_annotated_with = Composable 10 | # 2 is the default, but setting it to 1 forces all params on a multiline no matter what. 11 | ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2 12 | ktlint_standard_multiline-expression-wrapping = disabled 13 | ktlint_standard_string-template-indent = disabled 14 | -------------------------------------------------------------------------------- /.github/.java-version: -------------------------------------------------------------------------------- 1 | 23 2 | -------------------------------------------------------------------------------- /.github/actions/workflow_setup/action.yml: -------------------------------------------------------------------------------- 1 | name: "Workflow Setup" 2 | 3 | description: "Common setup across multiple workflows." 4 | 5 | runs: 6 | using: "composite" 7 | 8 | steps: 9 | - name: Set Up JDK 10 | uses: actions/setup-java@v4 11 | with: 12 | distribution: 'zulu' 13 | java-version-file: .github/.java-version 14 | 15 | - name: Setup Gradle 16 | uses: gradle/gradle-build-action@v3 17 | with: 18 | # Only write to the cache for builds on the 'development' branch 19 | cache-read-only: ${{ github.ref != 'refs/heads/development' }} -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | 4 | 5 | ## How It Was Tested 6 | 7 | 8 | 9 | ## Screenshot/Gif 10 | 11 | 12 | 13 |
14 | 15 | Screenshot Name 16 | 17 | 18 | 19 |
-------------------------------------------------------------------------------- /.github/workflows/android_build.yml: -------------------------------------------------------------------------------- 1 | name: Android Build 2 | 3 | # This will cancel any in progress workflows for the same PR, if 4 | # multiple pushes happen in quick succession. 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 7 | cancel-in-progress: true 8 | 9 | on: 10 | push: 11 | branches: 12 | - development 13 | pull_request: 14 | 15 | jobs: 16 | build: 17 | runs-on: macos-14 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Setup 22 | uses: ./.github/actions/workflow_setup 23 | 24 | - name: Build Project 25 | run: ./gradlew assemble 26 | 27 | - name: Run Tests 28 | run: ./gradlew test 29 | 30 | - name: Lint Checks 31 | run: ./gradlew detektAll lintKotlin lint 32 | 33 | - name: Dependency Sort Checks 34 | run: ./gradlew checkSortDependencies -------------------------------------------------------------------------------- /.github/workflows/android_ui_tests.yml: -------------------------------------------------------------------------------- 1 | name: Android UI Tests 2 | 3 | # This will cancel any in progress workflows for the same PR, if 4 | # multiple pushes happen in quick succession. 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 7 | cancel-in-progress: true 8 | 9 | on: 10 | pull_request: 11 | 12 | jobs: 13 | android-test: 14 | # At this moment in time, the emulator runner 15 | # does not work on macos-14: https://github.com/ReactiveCircus/android-emulator-runner/issues/392#issuecomment-2106167725 16 | runs-on: macos-13 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Setup 22 | uses: ./.github/actions/workflow_setup 23 | 24 | - name: Run Tests 25 | uses: reactivecircus/android-emulator-runner@v2 26 | with: 27 | api-level: 29 28 | script: ./gradlew app:connectedCheck -------------------------------------------------------------------------------- /.github/workflows/danger_checks.yml: -------------------------------------------------------------------------------- 1 | name: Danger Checks 2 | 3 | # This will cancel any in progress workflows for the same PR, if 4 | # multiple pushes happen in quick succession. 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 7 | cancel-in-progress: true 8 | 9 | on: pull_request 10 | 11 | jobs: 12 | danger: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup 19 | uses: ./.github/actions/workflow_setup 20 | 21 | - name: Dependency Updates 22 | run: ./gradlew dependencyUpdates 23 | 24 | - name: Danger Checks 25 | uses: danger/kotlin@1.3.3 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | -------------------------------------------------------------------------------- /.github/workflows/install_git_hooks_macos.yml: -------------------------------------------------------------------------------- 1 | # THIS ACTION IS FOR VALIDATION WITHIN TEMPLATE REPO, AND WILL BE 2 | # REMOVED UPON RUNNING RENAMETEMPLATE GRADLE TASK. 3 | 4 | name: Install MacOS Hooks 5 | 6 | # This will cancel any in progress workflows for the same PR, if 7 | # multiple pushes happen in quick succession. 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 10 | cancel-in-progress: true 11 | 12 | on: pull_request 13 | 14 | jobs: 15 | install-macos-hooks: 16 | runs-on: macos-14 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Setup 21 | uses: ./.github/actions/workflow_setup 22 | 23 | - name: Install 24 | run: ./gradlew installGitHooks 25 | 26 | - name: Check Pre-Commit File 27 | uses: GuillaumeFalourd/assert-command-line-output@v2.4 28 | with: 29 | command_line: cat .git/hooks/pre-commit 30 | assert_file_path: git-hooks/pre-commit-macos.sh 31 | expected_result: PASSED 32 | 33 | - name: Check Pre-Push File 34 | uses: GuillaumeFalourd/assert-command-line-output@v2.4 35 | with: 36 | command_line: cat .git/hooks/pre-push 37 | assert_file_path: git-hooks/pre-push-macos.sh 38 | expected_result: PASSED 39 | -------------------------------------------------------------------------------- /.github/workflows/install_git_hooks_windows.yml: -------------------------------------------------------------------------------- 1 | # THIS ACTION IS FOR VALIDATION WITHIN TEMPLATE REPO, AND WILL BE 2 | # REMOVED UPON RUNNING RENAMETEMPLATE GRADLE TASK. 3 | 4 | name: Install Windows Hooks 5 | 6 | # This will cancel any in progress workflows for the same PR, if 7 | # multiple pushes happen in quick succession. 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 10 | cancel-in-progress: true 11 | 12 | on: pull_request 13 | 14 | jobs: 15 | install-windows-hooks: 16 | runs-on: windows-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Setup 21 | uses: ./.github/actions/workflow_setup 22 | 23 | - name: Install 24 | run: ./gradlew installGitHooks 25 | 26 | - name: Check Pre-Commit File 27 | uses: GuillaumeFalourd/assert-command-line-output@v2.4 28 | with: 29 | command_line: cat .git/hooks/pre-commit 30 | assert_file_path: git-hooks/pre-commit-windows.sh 31 | expected_result: PASSED 32 | 33 | - name: Check Pre-Push File 34 | uses: GuillaumeFalourd/assert-command-line-output@v2.4 35 | with: 36 | command_line: cat .git/hooks/pre-push 37 | assert_file_path: git-hooks/pre-push-windows.sh 38 | expected_result: PASSED 39 | -------------------------------------------------------------------------------- /.github/workflows/template_change_test.yml: -------------------------------------------------------------------------------- 1 | # THIS ACTION IS FOR VALIDATION WITHIN TEMPLATE REPO, AND WILL BE 2 | # REMOVED UPON RUNNING RENAMETEMPLATE GRADLE TASK. 3 | 4 | name: Rename Template 5 | 6 | # This will cancel any in progress workflows for the same PR, if 7 | # multiple pushes happen in quick succession. 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 10 | cancel-in-progress: true 11 | 12 | on: pull_request 13 | 14 | jobs: 15 | rename-template: 16 | strategy: 17 | matrix: 18 | keepCustomizableDependencies: [true, false] 19 | fail-fast: false 20 | 21 | runs-on: macos-14 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: Setup 26 | uses: ./.github/actions/workflow_setup 27 | 28 | - name: Set useHiltDependencies 29 | run: | 30 | sed -i '' 's/useHiltDependencies.* : true/useHiltDependencies : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 31 | 32 | - name: Set useRoomDependencies 33 | run: | 34 | sed -i '' 's/useRoomDependencies.* : true/useRoomDependencies : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 35 | 36 | - name: Set useRetrofitDependencies 37 | run: | 38 | sed -i '' 's/useRetrofitDependencies.* : true/useRetrofitDependencies : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 39 | 40 | - name: Set usePaparazziDependencies 41 | run: | 42 | sed -i '' 's/usePaparazziDependencies.* : true/usePaparazziDependencies : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 43 | 44 | - name: Set useRenovateDependencies 45 | run: | 46 | sed -i '' 's/useRenovateDependencies.* : true/useRenovateDependencies : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 47 | 48 | - name: Set useAndroidXR 49 | run: | 50 | sed -i '' 's/useAndroidXR.* : false/useAndroidXR : ${{ matrix.keepCustomizableDependencies }}/g' buildscripts/setup.gradle 51 | 52 | - name: Rename 53 | run: ./gradlew renameTemplate 54 | 55 | - name: Lint Checks 56 | run: ./gradlew detektAll lintKotlin lint 57 | 58 | - name: Build 59 | run: ./gradlew assembleDebug -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/ 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | .kotlin/ 12 | -------------------------------------------------------------------------------- /Dangerfile.df.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("MagicNumber", "WildcardImport", "ForbiddenComment") 2 | 3 | // Editing this file: https://github.com/danger/kotlin?tab=readme-ov-file#autocomplete-and-syntax-highlighting-in-intellij-idea-or-android-studio 4 | import systems.danger.kotlin.* 5 | import java.io.File 6 | 7 | danger(args) { 8 | 9 | onGitHub { 10 | val additions = pullRequest.additions ?: 0 11 | val deletions = pullRequest.deletions ?: 0 12 | 13 | message("Thanks @${pullRequest.user.login}!") 14 | 15 | if (pullRequest.body.isNullOrBlank()) { 16 | fail("Please provide a summary in the Pull Request description.") 17 | } 18 | 19 | if (additions > 500) { 20 | warn("Please consider breaking up this pull request.") 21 | } 22 | 23 | if (issue.labels.isEmpty()) { 24 | warn("Please add labels to this PR.") 25 | } 26 | 27 | if (deletions > additions) { 28 | message("🎉 Code Cleanup!") 29 | } 30 | 31 | val updatesFile = File("build/dependencyUpdates/report.txt") 32 | val lines = updatesFile.readLines() 33 | 34 | val headerIndex = lines.indexOfFirst { line -> 35 | line.contains("The following dependencies have later milestone versions:") 36 | } 37 | 38 | if (headerIndex >= 0) { 39 | val message = lines.subList(headerIndex, lines.size).joinToString("\n") 40 | message(message) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android App Template 2 | 3 | This is a GitHub template repository intended to kickstart development on an Android application. This project comes set with a handful of tools that [Adam](https://github.com/AdamMc331) finds important and relevant to every project. If you think something is missing, or feel strongly that a setup should be changed, please submit an [Issue](https://github.com/AdamMc331/AndroidAppTemplate/issues/new). 4 | 5 | ## Why This Template? 6 | 7 | The purpose of this template is to avoid any opinions on writing code. The developers should have the freedom to choose their own architecture, third party dependencies, package structure, and more. 8 | 9 | This template _is_ opinionated about developer tooling. Dependency management is configured, git hooks are defined, code formatting and static analysis are all there, and it even has pull request templates. The purpose of this repo is to help you get started building your next project with confidence in your code, and not telling you how to write it. 10 | 11 | ## Walkthrough 12 | 13 | If you'd like a video walk through of this template and all it has to offer, you can find that on YouTube. 14 | 15 | https://youtu.be/E0iMUWJn76E 16 | 17 | ## Using This Template 18 | 19 | To use this template in your own project, click the "Use this template" button at the top right of the repository. Once you do, a repository will be created for your account that you can clone and use on your device. 20 | 21 | To setup this repository to your needs, open the [setup.gradle](buildscripts/setup.gradle) file 22 | and tweak the `renameConfig` block to your needs. After that, you can run the `renameTemplate` 23 | gradle task to have the app module's package name and relevant strings replaced. 24 | 25 | ### Cleanup 26 | 27 | After [this PR](https://github.com/AdamMc331/AndroidAppTemplate/pull/44), running the renameTemplate 28 | task should do all the necessary cleanup like deleting the setup file and test workflow so you can 29 | go ahead and commit the renamed files and be on your way. If you encounter any problems with the setup 30 | workflow, please report a new [issue](https://github.com/AdamMc331/AndroidAppTemplate/issues). 31 | 32 | ## What's Included 33 | 34 | A number of third party dependencies are included in this template. They are also documented inside the [documentation folder](/documentation). The files inside this documentation folder are written in such a way that you can keep them in your real project, to let team members read up on why dependencies are included and how they work. 35 | 36 | The dependencies in the template include: 37 | 38 | * [Ktlint](/documentation/StaticAnalysis.md) for formatting. 39 | * [Detekt](/documentation/StaticAnalysis.md) for code smells. 40 | * [Git Hooks](/documentation/GitHooks.md) for automatically perform static analysis checks. 41 | * [Gradle Versions Plugin](/documentation/VersionsPlugin.md) for checking all dependencies for new versions. 42 | * [GitHub Actions](/documentation/GitHubActions.md) for running continuous integration and ensuring code quality with every PR. 43 | * [LeakCanary](https://square.github.io/leakcanary/) for detecting memory leaks. 44 | * [Hilt](https://developer.android.com/training/dependency-injection/hilt-android) dependencies, which can be removed via setup.gradle if necessary. 45 | * [Room](https://developer.android.com/training/data-storage/room) dependencies, which can be removed via setup.gradle if necessary. 46 | * [Paparazzi](https://github.com/cashapp/paparazzi) dependncy, which can be removed via setup.gradle if necessary. 47 | 48 | ### Danger 49 | 50 | This template uses [Danger](https://danger.systems) which will perform some checks against our 51 | pull requests. You can find the list of checks in the [Dangerfile](Dangerfile.df.kts). In addition, we 52 | have a GitHub Actions workflow for Danger checks. In order for that to work properly, you'll 53 | need to give Danger permission to comment on your repository. 54 | 55 | You can do so by navigating to Repository Settings -> Actions -> General, scroll down to `Workflow Permissions` 56 | and set the permissions to read and write. 57 | 58 | ### Templates 59 | 60 | There are also templates within this template. This repo comes shipped with a [Pull Request Template](/.github/pull_request_template.md) that will help you and your team write organized and detailed pull request descriptions. 61 | 62 | ## Dependency Setup 63 | 64 | You may notice that dependencies are set up in a very specific way. Each of the tools has its own Gradle file in the [buildscripts folder](/buildscripts). This is by design so that if you chose to have a multi module project, these dependencies can easily be shared between them. This is already configured inside our root `build.gradle.kts` file, by applying to each sub project: 65 | 66 | ```groovy 67 | subprojects { 68 | apply from: "../buildscripts/detekt.gradle" 69 | apply from: "../buildscripts/versionsplugin.gradle" 70 | } 71 | ``` 72 | 73 | In addition, all of the app module dependencies are defined using a gradle version catalog, found in this [toml](gradle/libs.versions.toml) file. 74 | 75 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.application) 3 | alias(libs.plugins.cash.paparazzi) 4 | alias(libs.plugins.compose.compiler) 5 | alias(libs.plugins.google.dagger.hilt) 6 | alias(libs.plugins.google.ksp) 7 | alias(libs.plugins.kotlin.android) 8 | alias(libs.plugins.kotlin.parcelize) 9 | } 10 | 11 | android { 12 | compileSdk = libs.versions.compileSdk.get().toInt() 13 | 14 | defaultConfig { 15 | applicationId = "template.app.id" 16 | minSdk = libs.versions.minSdk.get().toInt() 17 | targetSdk = libs.versions.compileSdk.get().toInt() 18 | versionCode = 1 19 | versionName = "1.0" 20 | 21 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 22 | vectorDrawables { 23 | useSupportLibrary = true 24 | } 25 | } 26 | 27 | buildTypes { 28 | release { 29 | isMinifyEnabled = false 30 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 31 | } 32 | } 33 | 34 | compileOptions { 35 | sourceCompatibility = JavaVersion.VERSION_17 36 | targetCompatibility = JavaVersion.VERSION_17 37 | } 38 | 39 | kotlinOptions { 40 | jvmTarget = "17" 41 | } 42 | 43 | buildFeatures { 44 | compose = true 45 | } 46 | 47 | packaging { 48 | resources { 49 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 50 | } 51 | } 52 | 53 | namespace = "template" 54 | } 55 | 56 | dependencies { 57 | implementation(platform(libs.compose.bom)) 58 | implementation(libs.android.material) 59 | implementation(libs.androidx.activity.compose) 60 | implementation(libs.androidx.appcompat) 61 | implementation(libs.androidx.core.ktx) 62 | implementation(libs.androidx.lifecycle.runtime.ktx) 63 | implementation(libs.androidx.room.runtime) 64 | implementation(libs.bundles.androidx.xr) 65 | implementation(libs.coil.compose) 66 | implementation(libs.coil.okhttp) 67 | implementation(libs.compose.material) 68 | implementation(libs.compose.material.icons.extended) 69 | implementation(libs.compose.navigation) 70 | implementation(libs.compose.ui) 71 | implementation(libs.compose.ui.tooling) 72 | implementation(libs.hilt.android) 73 | implementation(libs.hilt.navigation.compose) 74 | implementation(libs.square.moshi.kotlin) 75 | implementation(libs.square.okhttp.logging.interceptor) 76 | implementation(libs.square.retrofit) 77 | implementation(libs.square.retrofit.converter.moshi) 78 | 79 | debugImplementation(platform(libs.compose.bom)) 80 | debugImplementation(libs.compose.ui.test.manifest) 81 | debugImplementation(libs.compose.ui.tooling) 82 | debugImplementation(libs.square.leakcanary) 83 | 84 | annotationProcessor(libs.androidx.room.compiler) 85 | 86 | testImplementation(libs.junit) 87 | 88 | androidTestImplementation(platform(libs.compose.bom)) 89 | androidTestImplementation(libs.androidx.test.espresso.core) 90 | androidTestImplementation(libs.androidx.test.junit) 91 | androidTestImplementation(libs.compose.ui.test.junit) 92 | androidTestImplementation(libs.hilt.android.testing) 93 | 94 | ksp(libs.androidx.room.compiler) 95 | ksp(libs.hilt.compiler) 96 | ksp(libs.square.moshi.kotlin.codegen) 97 | 98 | kspAndroidTest(libs.hilt.android.compiler) 99 | } 100 | 101 | tasks.formatKotlinMain { 102 | exclude { it.file.path.contains("build/")} 103 | } 104 | 105 | tasks.lintKotlinMain { 106 | exclude { it.file.path.contains("build/")} 107 | } 108 | -------------------------------------------------------------------------------- /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.kts. 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 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/template/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.compose.material3.MaterialTheme 8 | import androidx.compose.material3.Surface 9 | import androidx.compose.material3.Text 10 | import androidx.compose.runtime.Composable 11 | import dagger.hilt.android.AndroidEntryPoint 12 | import template.theme.TemplateTheme 13 | 14 | @AndroidEntryPoint 15 | class MainActivity : ComponentActivity() { 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | 19 | setContent { 20 | enableEdgeToEdge() 21 | 22 | TemplateTheme { 23 | Surface( 24 | color = MaterialTheme.colorScheme.background, 25 | ) { 26 | Greeting("Android") 27 | } 28 | } 29 | } 30 | } 31 | } 32 | 33 | @Composable 34 | fun Greeting(name: String) { 35 | Text(text = "Hello $name!") 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/template/TemplateApp.kt: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class TemplateApp : Application() 8 | -------------------------------------------------------------------------------- /app/src/main/java/template/theme/Color.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("MagicNumber") 2 | 3 | package template.theme 4 | 5 | import androidx.compose.ui.graphics.Color 6 | 7 | val Purple200 = Color(0xFFBB86FC) 8 | val Purple500 = Color(0xFF6200EE) 9 | val Teal200 = Color(0xFF03DAC5) 10 | -------------------------------------------------------------------------------- /app/src/main/java/template/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package template.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material3.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp), 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/template/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package template.theme 2 | 3 | import android.annotation.TargetApi 4 | import android.os.Build 5 | import androidx.compose.foundation.isSystemInDarkTheme 6 | import androidx.compose.material3.MaterialTheme 7 | import androidx.compose.material3.darkColorScheme 8 | import androidx.compose.material3.dynamicDarkColorScheme 9 | import androidx.compose.material3.dynamicLightColorScheme 10 | import androidx.compose.material3.lightColorScheme 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.ui.platform.LocalContext 13 | 14 | private val darkColorScheme = darkColorScheme( 15 | primary = Purple200, 16 | secondary = Teal200, 17 | ) 18 | 19 | private val lightColorScheme = lightColorScheme( 20 | primary = Purple500, 21 | secondary = Teal200, 22 | ) 23 | 24 | @Composable 25 | @TargetApi(Build.VERSION_CODES.S) 26 | fun TemplateTheme( 27 | darkTheme: Boolean = isSystemInDarkTheme(), 28 | dynamicTheme: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S, 29 | content: @Composable () -> Unit, 30 | ) { 31 | val colorScheme = when { 32 | dynamicTheme && darkTheme -> dynamicDarkColorScheme(LocalContext.current) 33 | dynamicTheme && !darkTheme -> dynamicLightColorScheme(LocalContext.current) 34 | darkTheme -> darkColorScheme 35 | else -> lightColorScheme 36 | } 37 | 38 | MaterialTheme( 39 | colorScheme = colorScheme, 40 | typography = Typography, 41 | shapes = Shapes, 42 | content = content, 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/template/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package template.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | bodyMedium = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | ), 16 | ) 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 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 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamMc331/AndroidAppTemplate/4381309db8f736a56863d8bc657949e83d69e27b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | template 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 21 | 22 |