├── .github └── workflows │ ├── app-build.yml │ └── publish.yml ├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml └── vcs.xml ├── License ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── canopas │ │ └── campose │ │ └── showcase │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── canopas │ │ │ └── campose │ │ │ └── showcase │ │ │ ├── MainActivity.kt │ │ │ └── ui │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Shape.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ └── res │ │ ├── drawable-v24 │ │ ├── ic_launcher_foreground.xml │ │ └── ic_unknown_profile.xml │ │ ├── drawable │ │ ├── go_back.png │ │ ├── ic_launcher_background.xml │ │ ├── right_arrow.png │ │ └── search_example.png │ │ ├── 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 │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── canopas │ └── campose │ └── showcase │ └── ExampleUnitTest.kt ├── build.gradle ├── docs ├── _config.yml ├── assets │ ├── 4- intro showcase.jpg │ ├── intro2.gif │ ├── intro3.gif │ └── main_intro.gif └── index.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts ├── publish-module.gradle └── publish-root.gradle ├── settings.gradle └── showcase ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── canopas │ └── lib │ └── showcase │ └── ExampleInstrumentedTest.kt ├── main ├── AndroidManifest.xml └── java │ └── com │ └── canopas │ └── lib │ └── showcase │ ├── IntroShowcase.kt │ └── component │ ├── IntroShowcaseState.kt │ ├── ShowcaseComposeView.kt │ └── ShowcaseContent.kt └── test └── java └── com └── canopas └── campos └── showcase └── ExampleUnitTest.kt /.github/workflows/app-build.yml: -------------------------------------------------------------------------------- 1 | name: Android Build 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: set up JDK 17 11 | uses: actions/setup-java@v2 12 | with: 13 | distribution: adopt 14 | java-version: 17 15 | - name: Build with Gradle 16 | run: ./gradlew build -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | push: 4 | tags: 5 | - '*' 6 | 7 | jobs: 8 | publish: 9 | name: Release build and publish 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out code 13 | uses: actions/checkout@v2 14 | - name: Set up JDK 17 15 | uses: actions/setup-java@v2 16 | with: 17 | distribution: adopt 18 | java-version: 17 19 | 20 | - name: Publish to MavenCentral 21 | run: ./gradlew showcase:publishReleasePublicationToSonatypeRepository --max-workers 1 closeAndReleaseSonatypeStagingRepository 22 | env: 23 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} 24 | OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} 25 | SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} 26 | SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} 27 | SIGNING_KEY: ${{ secrets.SIGNING_KEY }} 28 | SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} 29 | PUBLISH_VERSION: ${{ secrets.PUBLISH_VERSION }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | /local.properties 5 | /.idea/caches 6 | /.idea/libraries 7 | /.idea/modules.xml 8 | /.idea/workspace.xml 9 | /.idea/navEditor.xml 10 | /.idea/assetWizardSettings.xml 11 | .DS_Store 12 | /build 13 | /captures 14 | .externalNativeBuild 15 | .cxx 16 | local.properties 17 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Copyright 2022 Canopas Software LLP 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

cta_banner2

2 | 3 | # Intro Showcase View 4 | [![Android Arsenal]( https://img.shields.io/badge/Android%20Arsenal-Intro--showcase--view-green.svg?style=flat )]( https://android-arsenal.com/details/1/8387 ) 5 | Badge Badge 6 | 7 | 8 | 9 | 10 | An android library to highlight different features of the app built using Jetpack Compose. 11 | 12 | The library is inspired by the [TapTargetView](https://github.com/KeepSafe/TapTargetView) that is useful for legacy views. 13 | 14 | 15 | 16 | ## Configuration 17 | 18 | Available on [Maven Central](https://search.maven.org/artifact/com.canopas.intro-showcase-view/introshowcaseview). 19 | 20 | Add the dependency 21 | ```gradle 22 | implementation 'com.canopas.intro-showcase-view:introshowcaseview:2.0.1' 23 | 24 | ``` 25 | # Documentation 26 | Please see [sample application](https://github.com/canopas/Intro-showcase-view/tree/master/app) and [the website](https://canopas.github.io/compose-intro-showcase/) for more information. 27 | 28 | # Further reading 29 | For more details about the library implementation, checkout the [Article](https://blog.canopas.com/intro-showcase-view-in-jetpack-compose-ac044cd3bf28) 30 | 31 | # Bugs and Feedback 32 | For bugs, questions and discussions please use the [Github Issues](https://github.com/canopas/Intro-showcase-view/issues). 33 | 34 | # Credits 35 | 36 | Intro showcaseview is owned and maintained by the [Canopas team](https://canopas.com/). You can follow them on X at [@canopassoftware](https://x.com/canopassoftware) for project updates and releases. If you are interested in building apps or designing products, please let us know. We'd love to hear from you! 37 | 38 | 39 | 40 | # Licence 41 | 42 | ``` 43 | Copyright 2022 Canopas Software LLP 44 | 45 | Licensed under the Apache License, Version 2.0 (the "License"); 46 | you may not use this file except in compliance with the License. 47 | You may obtain a copy of the License at 48 | 49 | http://www.apache.org/licenses/LICENSE-2.0 50 | 51 | Unless required by applicable law or agreed to in writing, software 52 | distributed under the License is distributed on an "AS IS" BASIS, 53 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 54 | See the License for the specific language governing permissions and 55 | limitations under the License. 56 | ``` 57 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .idea -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace = "com.canopas.campose.showcase" 8 | compileSdk 34 9 | 10 | defaultConfig { 11 | applicationId "com.canopas.campose.jettaptarget" 12 | minSdk 21 13 | targetSdk 34 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | vectorDrawables { 19 | useSupportLibrary true 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_17 31 | targetCompatibility JavaVersion.VERSION_17 32 | } 33 | kotlinOptions { 34 | jvmTarget = '17' 35 | } 36 | buildFeatures { 37 | compose true 38 | } 39 | composeOptions { 40 | kotlinCompilerExtensionVersion compose_compiler_version 41 | } 42 | packagingOptions { 43 | resources { 44 | excludes += '/META-INF/{AL2.0,LGPL2.1}' 45 | } 46 | } 47 | } 48 | 49 | dependencies { 50 | implementation project(path: ':showcase') 51 | 52 | implementation platform("androidx.compose:compose-bom:$compose_bom_version") 53 | 54 | implementation 'androidx.core:core-ktx:1.12.0' 55 | implementation "androidx.compose.ui:ui" 56 | implementation "androidx.compose.material:material" 57 | implementation "androidx.compose.ui:ui-tooling-preview" 58 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' 59 | implementation 'androidx.activity:activity-compose:1.8.2' 60 | testImplementation 'junit:junit:4.13.2' 61 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 62 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 63 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.5.4" 64 | debugImplementation "androidx.compose.ui:ui-tooling" 65 | } -------------------------------------------------------------------------------- /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/canopas/campose/showcase/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.canopas.campose.jettaptarget", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/canopas/campose/showcase/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.foundation.Image 7 | import androidx.compose.foundation.layout.Arrangement 8 | import androidx.compose.foundation.layout.Box 9 | import androidx.compose.foundation.layout.Column 10 | import androidx.compose.foundation.layout.Row 11 | import androidx.compose.foundation.layout.Spacer 12 | import androidx.compose.foundation.layout.fillMaxHeight 13 | import androidx.compose.foundation.layout.fillMaxSize 14 | import androidx.compose.foundation.layout.fillMaxWidth 15 | import androidx.compose.foundation.layout.height 16 | import androidx.compose.foundation.layout.padding 17 | import androidx.compose.foundation.layout.size 18 | import androidx.compose.foundation.shape.CircleShape 19 | import androidx.compose.material.Button 20 | import androidx.compose.material.FloatingActionButton 21 | import androidx.compose.material.FloatingActionButtonDefaults 22 | import androidx.compose.material.Icon 23 | import androidx.compose.material.IconButton 24 | import androidx.compose.material.MaterialTheme 25 | import androidx.compose.material.Scaffold 26 | import androidx.compose.material.Surface 27 | import androidx.compose.material.Text 28 | import androidx.compose.material.TopAppBar 29 | import androidx.compose.material.icons.Icons 30 | import androidx.compose.material.icons.filled.ArrowBack 31 | import androidx.compose.material.icons.filled.Email 32 | import androidx.compose.material.icons.filled.Search 33 | import androidx.compose.runtime.Composable 34 | import androidx.compose.runtime.getValue 35 | import androidx.compose.runtime.mutableStateOf 36 | import androidx.compose.runtime.remember 37 | import androidx.compose.runtime.setValue 38 | import androidx.compose.ui.Alignment 39 | import androidx.compose.ui.Modifier 40 | import androidx.compose.ui.draw.clip 41 | import androidx.compose.ui.graphics.Color 42 | import androidx.compose.ui.res.painterResource 43 | import androidx.compose.ui.text.font.FontWeight 44 | import androidx.compose.ui.text.style.TextAlign 45 | import androidx.compose.ui.unit.dp 46 | import androidx.compose.ui.unit.sp 47 | import com.canopas.campose.showcase.ui.theme.JetTapTargetTheme 48 | import com.canopas.campose.showcase.ui.theme.ThemeColor 49 | import com.canopas.lib.showcase.IntroShowcase 50 | import com.canopas.lib.showcase.IntroShowcaseScope 51 | import com.canopas.lib.showcase.component.IntroShowcaseState 52 | import com.canopas.lib.showcase.component.ShowcaseStyle 53 | import com.canopas.lib.showcase.component.rememberIntroShowcaseState 54 | 55 | class MainActivity : ComponentActivity() { 56 | override fun onCreate(savedInstanceState: Bundle?) { 57 | super.onCreate(savedInstanceState) 58 | 59 | setContent { 60 | JetTapTargetTheme { 61 | // A surface container using the 'background' color from the theme 62 | Surface( 63 | modifier = Modifier 64 | .fillMaxSize(), 65 | color = MaterialTheme.colors.background 66 | ) { 67 | ShowcaseSample() 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | @Composable 75 | fun ShowcaseSample() { 76 | var showAppIntro by remember { 77 | mutableStateOf(true) 78 | } 79 | 80 | val introShowcaseState = rememberIntroShowcaseState() 81 | 82 | IntroShowcase( 83 | showIntroShowCase = showAppIntro, 84 | dismissOnClickOutside = false, 85 | onShowCaseCompleted = { 86 | //App Intro finished!! 87 | showAppIntro = false 88 | }, 89 | state = introShowcaseState, 90 | ) { 91 | Scaffold( 92 | modifier = Modifier.fillMaxSize(), 93 | topBar = { 94 | TopAppBar( 95 | title = { }, 96 | backgroundColor = Color.Transparent, 97 | elevation = 0.dp, 98 | navigationIcon = { 99 | BackButton(introShowcaseState) 100 | }, 101 | actions = { 102 | IconButton( 103 | onClick = {}, 104 | modifier = Modifier.introShowCaseTarget( 105 | index = 0, 106 | style = ShowcaseStyle.Default.copy( 107 | backgroundColor = Color(0xFF9AD0EC), // specify color of background 108 | backgroundAlpha = 0.98f, // specify transparency of background 109 | targetCircleColor = Color.White // specify color of target circle 110 | ), 111 | content = { 112 | Column { 113 | Image( 114 | painterResource(id = R.drawable.search_example), 115 | contentDescription = null, 116 | modifier = Modifier.size(100.dp) 117 | ) 118 | 119 | Text( 120 | text = "Search anything!!", 121 | color = Color.Black, 122 | fontSize = 24.sp, 123 | fontWeight = FontWeight.Bold 124 | ) 125 | Text( 126 | text = "You can search anything by clicking here.", 127 | color = Color.Black, 128 | fontSize = 16.sp 129 | ) 130 | } 131 | } 132 | ) 133 | ) { 134 | Icon(Icons.Filled.Search, contentDescription = "Search") 135 | } 136 | } 137 | ) 138 | }, 139 | floatingActionButton = { 140 | FloatingMailButton() 141 | } 142 | ) { 143 | Content(Modifier.padding(it)) 144 | } 145 | } 146 | } 147 | 148 | 149 | @Composable 150 | fun IntroShowcaseScope.FloatingMailButton() { 151 | FloatingActionButton( 152 | onClick = {}, 153 | modifier = Modifier.introShowCaseTarget( 154 | index = 1, 155 | style = ShowcaseStyle.Default.copy( 156 | backgroundColor = Color(0xFF1C0A00), // specify color of background 157 | backgroundAlpha = 0.98f, // specify transparency of background 158 | targetCircleColor = Color.White // specify color of target circle 159 | ), 160 | // specify the content to show to introduce app feature 161 | content = { 162 | Column { 163 | Text( 164 | text = "Check emails", 165 | color = Color.White, 166 | fontSize = 24.sp, 167 | fontWeight = FontWeight.Bold 168 | ) 169 | Text( 170 | text = "Click here to check/send emails", 171 | color = Color.White, 172 | fontSize = 16.sp 173 | ) 174 | Spacer(modifier = Modifier.height(10.dp)) 175 | Icon( 176 | painterResource(id = R.drawable.right_arrow), 177 | contentDescription = null, 178 | modifier = Modifier 179 | .size(80.dp) 180 | .align(Alignment.End), 181 | tint = Color.White 182 | ) 183 | } 184 | } 185 | ), 186 | backgroundColor = ThemeColor, 187 | contentColor = Color.White, 188 | elevation = FloatingActionButtonDefaults.elevation(6.dp) 189 | ) { 190 | Icon( 191 | Icons.Filled.Email, 192 | contentDescription = "Email" 193 | ) 194 | } 195 | 196 | } 197 | 198 | @Composable 199 | fun IntroShowcaseScope.BackButton(introShowcaseState: IntroShowcaseState) { 200 | IconButton( 201 | onClick = {}, 202 | modifier = Modifier.introShowCaseTarget( 203 | index = 4, 204 | style = ShowcaseStyle.Default.copy( 205 | backgroundColor = Color(0xFF7C99AC), // specify color of background 206 | backgroundAlpha = 0.98f, // specify transparency of background 207 | targetCircleColor = Color.White // specify color of target circle 208 | ), 209 | content = { 210 | Row(verticalAlignment = Alignment.CenterVertically) { 211 | Image( 212 | painterResource(id = R.drawable.go_back), 213 | contentDescription = null, 214 | modifier = Modifier 215 | .size(100.dp) 216 | .padding(top = 10.dp) 217 | ) 218 | Column { 219 | Text( 220 | text = "Go back!!", 221 | color = Color.White, 222 | fontSize = 24.sp, 223 | fontWeight = FontWeight.Bold 224 | ) 225 | Text( 226 | text = "You can go back by clicking here.", 227 | color = Color.White, 228 | fontSize = 16.sp 229 | ) 230 | 231 | Button( 232 | onClick = { 233 | // Used to restart the intro showcase 234 | introShowcaseState.reset() 235 | }, 236 | ) { 237 | Text(text = "Restart Intro") 238 | } 239 | } 240 | } 241 | }, 242 | ) 243 | ) { 244 | Icon(Icons.Filled.ArrowBack, contentDescription = "Search") 245 | } 246 | } 247 | 248 | @Composable 249 | fun IntroShowcaseScope.Content(modifier: Modifier) { 250 | Box(modifier = modifier.fillMaxSize()) { 251 | Box(modifier = Modifier.fillMaxHeight(0.3f)) { 252 | 253 | Column( 254 | Modifier 255 | .align(Alignment.BottomStart) 256 | .fillMaxWidth() 257 | .padding(16.dp) 258 | .height(90.dp), 259 | verticalArrangement = Arrangement.Center, 260 | horizontalAlignment = Alignment.CenterHorizontally 261 | ) { 262 | 263 | Text( 264 | text = "Intro Showcase view", fontWeight = FontWeight.Bold, 265 | fontSize = 24.sp, color = ThemeColor 266 | ) 267 | Text( 268 | text = "This is an example of Intro Showcase view", 269 | fontSize = 20.sp, color = Color.Black, textAlign = TextAlign.Center 270 | ) 271 | 272 | } 273 | 274 | Image( 275 | painter = painterResource(id = R.drawable.ic_unknown_profile), 276 | contentDescription = null, 277 | modifier = Modifier 278 | .align(Alignment.TopCenter) 279 | .clip(CircleShape) 280 | .introShowCaseTarget( 281 | index = 2, // specify index to show feature in order 282 | // ShowcaseStyle is optional 283 | style = ShowcaseStyle.Default.copy( 284 | backgroundColor = Color(0xFFFFCC80), // specify color of background 285 | backgroundAlpha = 0.98f, // specify transparency of background 286 | targetCircleColor = Color.White // specify color of target circle 287 | ), 288 | content = { 289 | Column( 290 | horizontalAlignment = Alignment.CenterHorizontally, 291 | modifier = Modifier 292 | .fillMaxWidth() 293 | .padding(top = 20.dp) 294 | ) { 295 | Text( 296 | text = "User profile", 297 | color = Color.White, 298 | fontSize = 24.sp, 299 | fontWeight = FontWeight.Bold 300 | ) 301 | Text( 302 | text = "Click here to update your profile", 303 | color = Color.White, 304 | fontSize = 16.sp 305 | ) 306 | } 307 | } 308 | ) 309 | ) 310 | } 311 | 312 | Button( 313 | onClick = {}, 314 | modifier = Modifier 315 | .align(Alignment.BottomStart) 316 | .padding(start = 16.dp, bottom = 16.dp) 317 | .introShowCaseTarget( 318 | index = 3, 319 | content = { 320 | Column { 321 | Text( 322 | text = "Follow me", 323 | color = Color.White, 324 | fontSize = 24.sp, 325 | fontWeight = FontWeight.Bold 326 | ) 327 | Text( 328 | text = "Click here to follow", 329 | color = Color.White, 330 | fontSize = 16.sp 331 | ) 332 | } 333 | } 334 | ) 335 | ) { 336 | Text(text = "Follow") 337 | } 338 | } 339 | 340 | } 341 | 342 | -------------------------------------------------------------------------------- /app/src/main/java/com/canopas/campose/showcase/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Teal200 = Color(0xFF03DAC5) 6 | val WhiteSecondary = Color(0xFFF5F5F5) 7 | val ThemeColor = Color(0xFFFB709A) 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/canopas/campose/showcase/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase.ui.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.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 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/canopas/campose/showcase/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase.ui.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = ThemeColor, 11 | primaryVariant = ThemeColor, 12 | secondary = Teal200 13 | ) 14 | 15 | private val LightColorPalette = lightColors( 16 | primary = ThemeColor, 17 | primaryVariant = ThemeColor, 18 | secondary = Teal200, 19 | background = WhiteSecondary, 20 | surface = WhiteSecondary, 21 | /* Other default colors to override 22 | background = Color.White, 23 | surface = Color.White, 24 | onPrimary = Color.White, 25 | onSecondary = Color.Black, 26 | onBackground = Color.Black, 27 | onSurface = Color.Black, 28 | */ 29 | ) 30 | 31 | @Composable 32 | fun JetTapTargetTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { 33 | val colors = if (darkTheme) { 34 | DarkColorPalette 35 | } else { 36 | LightColorPalette 37 | } 38 | 39 | MaterialTheme( 40 | colors = colors, 41 | typography = Typography, 42 | shapes = Shapes, 43 | content = content 44 | ) 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/canopas/campose/showcase/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.canopas.campose.showcase.ui.theme 2 | 3 | import androidx.compose.material.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 | body1 = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp 15 | ) 16 | /* Other default text styles to override 17 | button = TextStyle( 18 | fontFamily = FontFamily.Default, 19 | fontWeight = FontWeight.W500, 20 | fontSize = 14.sp 21 | ), 22 | caption = TextStyle( 23 | fontFamily = FontFamily.Default, 24 | fontWeight = FontWeight.Normal, 25 | fontSize = 12.sp 26 | ) 27 | */ 28 | ) -------------------------------------------------------------------------------- /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-v24/ic_unknown_profile.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/drawable/go_back.png -------------------------------------------------------------------------------- /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/drawable/right_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/drawable/right_arrow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/drawable/search_example.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canopas/compose-intro-showcase/a520a4733d7a85ebb1a74a88a1acf5d9e9f6b0cc/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | #F5F5F5 11 | #FFFF7373 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Intro Showcase 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |