Skip to content

Commit 5b778ab

Browse files
Merge pull request #4 from SimformSolutionsPvtLtd/feature/UNT-T9788
UNT-T9788 LGTM.
2 parents dfe30a8 + e3bb8c5 commit 5b778ab

6 files changed

Lines changed: 95 additions & 42 deletions

File tree

app/build.gradle

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ plugins {
44
}
55

66
android {
7-
compileSdk 32
7+
compileSdk 33
88

99
defaultConfig {
1010
applicationId "com.example.sscomposeshowcaseview"
1111
minSdk 21
12-
targetSdk 32
12+
targetSdk 33
1313
versionCode 1
1414
versionName "1.0"
1515

@@ -39,22 +39,22 @@ android {
3939

4040
dependencies {
4141

42-
implementation 'androidx.core:core-ktx:1.8.0'
43-
implementation 'androidx.appcompat:appcompat:1.4.2'
42+
implementation 'androidx.core:core-ktx:1.9.0'
43+
implementation 'androidx.appcompat:appcompat:1.5.1'
4444
implementation 'com.google.android.material:material:1.6.1'
4545
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
46-
implementation 'androidx.activity:activity-compose:1.4.0'
47-
implementation 'androidx.compose.material:material:1.1.1'
48-
implementation 'androidx.compose.animation:animation:1.1.1'
49-
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
50-
implementation 'androidx.compose.ui:ui-tooling:1.1.1'
46+
implementation 'androidx.activity:activity-compose:1.6.0'
47+
implementation 'androidx.compose.material:material:1.2.1'
48+
implementation 'androidx.compose.animation:animation:1.2.1'
49+
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.2.1'
50+
implementation 'androidx.compose.ui:ui-tooling:1.2.1'
5151
testImplementation 'junit:junit:4.13.2'
5252
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
5353
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
54-
implementation "com.google.android.material:compose-theme-adapter:1.1.11"
54+
implementation "com.google.android.material:compose-theme-adapter:1.1.20"
5555
implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
5656
implementation project(':sscomposeshowcaseview')
57-
implementation 'androidx.compose.ui:ui-tooling-preview:1.1.1'
58-
debugImplementation "androidx.customview:customview:1.2.0-alpha01"
59-
debugImplementation "androidx.customview:customview-poolingcontainer:1.0.0-rc01"
57+
implementation 'androidx.compose.ui:ui-tooling-preview:1.2.1'
58+
debugImplementation "androidx.customview:customview:1.2.0-alpha02"
59+
debugImplementation "androidx.customview:customview-poolingcontainer:1.0.0"
6060
}

app/src/main/java/com/example/sscomposeshowcaseview/MainActivity.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ import androidx.compose.ui.platform.LocalContext
4646
import androidx.compose.ui.res.painterResource
4747
import androidx.compose.ui.tooling.preview.Preview
4848
import androidx.compose.ui.unit.dp
49+
import kotlinx.coroutines.CoroutineScope
50+
import kotlinx.coroutines.Dispatchers
51+
import kotlinx.coroutines.launch
4952

5053
class MainActivity : ComponentActivity() {
5154
override fun onCreate(savedInstanceState: Bundle?) {
@@ -67,9 +70,11 @@ private fun ShowcaseExample() {
6770
}
6871
}
6972

70-
ShowCaseTarget(targets = targets) {
71-
Toast.makeText(context, "Thank you! Intro Completed", Toast.LENGTH_SHORT)
72-
.show()
73+
ShowCaseTarget(targets = targets, isEnableAutoShowCase = true, key = "Dashboard") {
74+
CoroutineScope(Dispatchers.Main).launch {
75+
Toast.makeText(context, "Thank you! Intro Completed", Toast.LENGTH_SHORT)
76+
.show()
77+
}
7378
}
7479
}
7580

@@ -133,7 +138,8 @@ fun UserProfile(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>)
133138
coordinates = it,
134139
title = "More options",
135140
subTitle = "Click here to see options",
136-
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
141+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE,
142+
showcaseDelay = 5000
137143
)
138144
}
139145
)
@@ -173,7 +179,8 @@ fun UserPost(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>) {
173179
coordinates = it,
174180
title = "LIke Post",
175181
subTitle = "Click here to like post",
176-
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
182+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE,
183+
showcaseDelay = 500
177184
)
178185
}
179186
)
@@ -191,7 +198,8 @@ fun UserPost(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>) {
191198
coordinates = it,
192199
title = "Comment button",
193200
subTitle = "Click here to add comment on post",
194-
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
201+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE,
202+
showcaseDelay = 1000
195203
)
196204
}
197205
)

sscomposeshowcaseview/build.gradle

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ plugins {
44
}
55

66
android {
7-
compileSdk 32
7+
compileSdk 33
88

99
defaultConfig {
1010
minSdk 21
11-
targetSdk 32
11+
targetSdk 33
1212

1313
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1414
consumerProguardFiles "consumer-rules.pro"
@@ -37,22 +37,22 @@ android {
3737

3838
dependencies {
3939

40-
implementation 'androidx.core:core-ktx:1.8.0'
41-
implementation 'androidx.appcompat:appcompat:1.4.2'
40+
implementation 'androidx.core:core-ktx:1.9.0'
41+
implementation 'androidx.appcompat:appcompat:1.5.1'
4242
implementation 'com.google.android.material:material:1.6.1'
4343
testImplementation 'junit:junit:4.13.2'
4444
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
4545
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
46-
implementation "com.google.android.material:compose-theme-adapter:1.1.11"
46+
implementation "com.google.android.material:compose-theme-adapter:1.1.20"
4747
implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
4848

4949
//Compose
50-
implementation 'androidx.activity:activity-compose:1.4.0'
51-
implementation 'androidx.compose.material:material:1.1.1'
52-
implementation 'androidx.compose.animation:animation:1.1.1'
53-
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
54-
implementation 'androidx.compose.ui:ui-tooling:1.1.1'
55-
implementation 'androidx.compose.ui:ui-tooling-preview:1.1.1'
56-
debugImplementation "androidx.customview:customview:1.2.0-alpha01"
57-
debugImplementation "androidx.customview:customview-poolingcontainer:1.0.0-rc01"
50+
implementation 'androidx.activity:activity-compose:1.6.0'
51+
implementation 'androidx.compose.material:material:1.2.1'
52+
implementation 'androidx.compose.animation:animation:1.2.1'
53+
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.2.1'
54+
implementation 'androidx.compose.ui:ui-tooling:1.2.1'
55+
implementation 'androidx.compose.ui:ui-tooling-preview:1.2.1'
56+
debugImplementation "androidx.customview:customview:1.2.0-alpha02"
57+
debugImplementation "androidx.customview:customview-poolingcontainer:1.0.0"
5858
}

sscomposeshowcaseview/src/main/java/com/example/sscomposeshowcaseview/ShowcaseProperty.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ data class ShowcaseProperty(
1010
val titleColor: Color = Color.White,
1111
val subTitle: String,
1212
val subTitleColor: Color = Color.White,
13-
val showCaseType: ShowcaseType = ShowcaseType.SIMPLE_ROUNDED
13+
val showCaseType: ShowcaseType = ShowcaseType.SIMPLE_ROUNDED,
14+
val blurOpacity: Float = 0.8f,
15+
val showcaseDelay: Long = 2000
1416
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example.sscomposeshowcaseview
2+
3+
import android.content.Context
4+
import android.content.SharedPreferences
5+
6+
class Preferences(private val context: Context) {
7+
8+
fun show(key: String) {
9+
val preferences: SharedPreferences = context.getSharedPreferences(SHOWCASE_VIEW_JETPACK, Context.MODE_PRIVATE)
10+
val editor: SharedPreferences.Editor = preferences.edit()
11+
editor.putBoolean(key, true)
12+
editor.apply()
13+
}
14+
15+
fun getShowing(key: String): Boolean {
16+
val preferences: SharedPreferences = context.getSharedPreferences(SHOWCASE_VIEW_JETPACK, Context.MODE_PRIVATE)
17+
return preferences.getBoolean(key, false)
18+
}
19+
20+
companion object {
21+
const val SHOWCASE_VIEW_JETPACK = "SHOWCASE_VIEW_JETPACK"
22+
}
23+
24+
}

sscomposeshowcaseview/src/main/java/com/example/sscomposeshowcaseview/ShowcaseView.kt

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ import androidx.compose.ui.layout.boundsInRoot
3636
import androidx.compose.ui.layout.onGloballyPositioned
3737
import androidx.compose.ui.layout.positionInRoot
3838
import androidx.compose.ui.platform.LocalConfiguration
39+
import androidx.compose.ui.platform.LocalContext
3940
import androidx.compose.ui.platform.LocalDensity
4041
import androidx.compose.ui.text.font.FontWeight
4142
import androidx.compose.ui.unit.dp
4243
import androidx.compose.ui.unit.sp
4344
import kotlinx.coroutines.delay
45+
import java.util.Timer
46+
import kotlin.concurrent.schedule
4447
import kotlin.math.max
4548
import kotlin.math.min
4649
import kotlin.math.pow
@@ -53,19 +56,27 @@ import kotlin.math.sqrt
5356
@Composable
5457
fun ShowCaseTarget(
5558
targets: SnapshotStateMap<String, ShowcaseProperty>,
59+
isEnableAutoShowCase: Boolean = false,
60+
key: String,
5661
onShowCaseCompleted: () -> Unit
5762
) {
63+
val preferences = Preferences(context = LocalContext.current)
5864
val uniqueTargets = targets.values.sortedBy { it.index }
5965
var currentTargetIndex by remember { mutableStateOf(0) }
6066
val currentTarget = if (uniqueTargets.isNotEmpty() && currentTargetIndex < uniqueTargets.size)
6167
uniqueTargets[currentTargetIndex]
6268
else
6369
null
6470

71+
if (preferences.getShowing(key)) {
72+
return
73+
}
74+
6575
currentTarget?.let {
66-
IntroShowCase(targets = it) {
76+
IntroShowCase(targets = it, isAutomaticShowcase = isEnableAutoShowCase) {
6777
if (++currentTargetIndex >= uniqueTargets.size) {
6878
onShowCaseCompleted()
79+
preferences.show(key)
6980
}
7081
}
7182
}
@@ -77,7 +88,9 @@ fun ShowCaseTarget(
7788
* @param onShowCaseCompleted do the needful on completing showcase view.
7889
*/
7990
@Composable
80-
fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
91+
fun IntroShowCase(
92+
targets: ShowcaseProperty, isAutomaticShowcase: Boolean = false, onShowCaseCompleted: () -> Unit
93+
) {
8194
val targetRect = targets.coordinates.boundsInRoot()
8295
val targetRadius = targetRect.maxDimension / 2f + 20
8396
val xOffset = targetRect.topLeft.x
@@ -139,10 +152,16 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
139152
modifier = Modifier
140153
.fillMaxSize()
141154
.pointerInput(targets) {
142-
detectTapGestures { tapOffset ->
143-
if (targetRect.contains(tapOffset)) {
155+
if (isAutomaticShowcase) {
156+
Timer(true).schedule(targets.showcaseDelay) {
144157
onShowCaseCompleted()
145158
}
159+
} else {
160+
detectTapGestures { tapOffset ->
161+
if (targetRect.contains(tapOffset)) {
162+
onShowCaseCompleted()
163+
}
164+
}
146165
}
147166
}
148167
.graphicsLayer(alpha = 0.99f)
@@ -153,7 +172,7 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
153172
*/
154173
ShowcaseType.SIMPLE_ROUNDED -> {
155174
drawCircle(
156-
color = Color.Black.copy(alpha = 0.8f),
175+
color = Color.Black.copy(alpha = targets.blurOpacity),
157176
radius = size.maxDimension,
158177
alpha = 0.9f
159178
)
@@ -169,7 +188,7 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
169188
*/
170189
ShowcaseType.SIMPLE_RECTANGLE -> {
171190
drawRect(
172-
Color.Black.copy(alpha = 0.8f),
191+
Color.Black.copy(alpha = targets.blurOpacity),
173192
size = Size(size.width + 40f, size.height + 40f),
174193
style = Fill,
175194
)
@@ -189,7 +208,7 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
189208
color = Color.Black,
190209
center = outerOffset,
191210
radius = outerRadius * outerAnimaTable.value,
192-
alpha = 0.9f
211+
alpha = targets.blurOpacity
193212
)
194213
// draw circle with animation
195214
dys.forEach { dy ->
@@ -212,7 +231,7 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
212231
*/
213232
ShowcaseType.ANIMATED_RECTANGLE -> {
214233
drawRect(
215-
Color.Black.copy(alpha = 0.8f),
234+
Color.Black.copy(alpha = targets.blurOpacity),
216235
size = Size(size.width + 40f, size.height + 40f),
217236
style = Fill,
218237
)
@@ -225,7 +244,7 @@ fun IntroShowCase(targets: ShowcaseProperty, onShowCaseCompleted: () -> Unit) {
225244
)
226245
dys.forEach { dy ->
227246
drawRect(
228-
color = Color.White.copy(alpha = 0.8f),
247+
color = Color.White.copy(alpha = targets.blurOpacity),
229248
size = Size(rectSize.width * dy * 2, rectSize.height * dy * 2),
230249
topLeft = Offset(xOffset - 12, yOffset - 12),
231250
alpha = 1 - dy

0 commit comments

Comments
 (0)