Skip to content

Commit dfe30a8

Browse files
Merge pull request #2 from SimformSolutionsPvtLtd/feature/UNT-T8172
UNT-T8172: Added ShowcaseView with rounded and rectangle showcase. LGTM.
2 parents 8a82914 + 9018c65 commit dfe30a8

9 files changed

Lines changed: 645 additions & 4 deletions

File tree

app/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,8 @@ dependencies {
5353
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
5454
implementation "com.google.android.material:compose-theme-adapter:1.1.11"
5555
implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
56+
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"
5660
}
Lines changed: 227 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,248 @@
11
package com.example.sscomposeshowcaseview
22

33
import android.os.Bundle
4+
import android.widget.Toast
45
import androidx.activity.ComponentActivity
56
import androidx.activity.compose.setContent
7+
import androidx.compose.foundation.Image
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.fillMaxWidth
13+
import androidx.compose.foundation.layout.height
14+
import androidx.compose.foundation.layout.padding
15+
import androidx.compose.foundation.layout.size
16+
import androidx.compose.foundation.layout.width
17+
import androidx.compose.foundation.lazy.LazyColumn
18+
import androidx.compose.foundation.lazy.items
19+
import androidx.compose.foundation.shape.CircleShape
20+
import androidx.compose.material.Divider
21+
import androidx.compose.material.Icon
22+
import androidx.compose.material.IconButton
23+
import androidx.compose.material.Scaffold
24+
import androidx.compose.material.Surface
625
import androidx.compose.material.Text
26+
import androidx.compose.material.TopAppBar
27+
import androidx.compose.material.icons.Icons
28+
import androidx.compose.material.icons.filled.Add
29+
import androidx.compose.material.icons.filled.Favorite
30+
import androidx.compose.material.icons.filled.FavoriteBorder
31+
import androidx.compose.material.icons.filled.Menu
32+
import androidx.compose.material.icons.filled.MoreVert
33+
import androidx.compose.material.icons.filled.Share
34+
import androidx.compose.material.icons.outlined.Star
735
import androidx.compose.runtime.Composable
36+
import androidx.compose.runtime.mutableStateMapOf
37+
import androidx.compose.runtime.mutableStateOf
38+
import androidx.compose.runtime.remember
39+
import androidx.compose.runtime.snapshots.SnapshotStateMap
40+
import androidx.compose.ui.Alignment
41+
import androidx.compose.ui.Modifier
42+
import androidx.compose.ui.draw.clip
43+
import androidx.compose.ui.layout.ContentScale
44+
import androidx.compose.ui.layout.onGloballyPositioned
45+
import androidx.compose.ui.platform.LocalContext
46+
import androidx.compose.ui.res.painterResource
847
import androidx.compose.ui.tooling.preview.Preview
48+
import androidx.compose.ui.unit.dp
949

1050
class MainActivity : ComponentActivity() {
1151
override fun onCreate(savedInstanceState: Bundle?) {
1252
super.onCreate(savedInstanceState)
1353
setContent {
14-
54+
ShowcaseExample()
55+
}
56+
}
57+
}
58+
59+
@Composable
60+
private fun ShowcaseExample() {
61+
val targets = remember { mutableStateMapOf<String, ShowcaseProperty>() }
62+
val context = LocalContext.current
63+
64+
Scaffold(topBar = { TopAppBar(target = targets) }) {
65+
Column(modifier = Modifier.padding(it)) {
66+
Posts(target = targets)
67+
}
68+
}
69+
70+
ShowCaseTarget(targets = targets) {
71+
Toast.makeText(context, "Thank you! Intro Completed", Toast.LENGTH_SHORT)
72+
.show()
73+
}
74+
}
75+
76+
@Composable
77+
private fun TopAppBar(target: SnapshotStateMap<String, ShowcaseProperty>) {
78+
TopAppBar(title = { Text(text = "SSShowcaseView") },
79+
navigationIcon = {
80+
Icon(imageVector = Icons.Filled.Menu, contentDescription = "Menu")
81+
}
82+
)
83+
}
84+
85+
@Composable
86+
private fun Posts(target: SnapshotStateMap<String, ShowcaseProperty>) {
87+
LazyColumn {
88+
items(items = Data.userList) { item ->
89+
PostItem(post = item, target = target)
90+
}
91+
}
92+
}
93+
94+
@Composable
95+
fun PostItem(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>) {
96+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
97+
UserProfile(post = post, target = target)
98+
Divider(Modifier.fillMaxWidth(), thickness = 1.dp)
99+
UserPost(post = post, target = target)
100+
}
101+
}
102+
103+
@Composable
104+
fun UserProfile(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>) {
105+
Row(verticalAlignment = Alignment.CenterVertically,
106+
modifier = Modifier.onGloballyPositioned {
107+
target["profile"] = ShowcaseProperty(
108+
index = 6,
109+
coordinates = it,
110+
title = "Profile",
111+
subTitle = "User Profile with name and picture",
112+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
113+
)
114+
}) {
115+
Image(
116+
painter = painterResource(id = post.profilePic),
117+
contentDescription = "User profile pic",
118+
contentScale = ContentScale.Crop,
119+
modifier = Modifier
120+
.padding(10.dp)
121+
.clip(CircleShape)
122+
.size(30.dp)
123+
)
124+
Text(text = post.name, modifier = Modifier.weight(1f))
125+
Image(
126+
imageVector = Icons.Default.MoreVert,
127+
contentDescription = "More icon",
128+
modifier = Modifier
129+
.padding(10.dp)
130+
.onGloballyPositioned {
131+
target["more"] = ShowcaseProperty(
132+
index = 1,
133+
coordinates = it,
134+
title = "More options",
135+
subTitle = "Click here to see options",
136+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
137+
)
138+
}
139+
)
140+
}
141+
}
142+
143+
@Composable
144+
fun UserPost(post: Item, target: SnapshotStateMap<String, ShowcaseProperty>) {
145+
val isLikeClicked = remember { mutableStateOf(true) }
146+
Column(modifier = Modifier.fillMaxWidth()) {
147+
Image(
148+
painter = painterResource(id = post.profilePic),
149+
contentDescription = "User post",
150+
modifier = Modifier
151+
.fillMaxWidth()
152+
.height(450.dp),
153+
contentScale = ContentScale.Crop
154+
)
155+
Box(
156+
modifier = Modifier
157+
.fillMaxWidth()
158+
.padding(start = 8.dp, bottom = 12.dp)
159+
) {
160+
Row(
161+
modifier = Modifier.fillMaxWidth(),
162+
verticalAlignment = Alignment.CenterVertically
163+
) {
164+
IconButton(onClick = { isLikeClicked.value = !isLikeClicked.value }) {
165+
Icon(
166+
imageVector = if (isLikeClicked.value) Icons.Default.FavoriteBorder else Icons.Filled.Favorite,
167+
contentDescription = "Fav",
168+
modifier = Modifier
169+
.size(30.dp)
170+
.onGloballyPositioned {
171+
target["like"] = ShowcaseProperty(
172+
index = 2,
173+
coordinates = it,
174+
title = "LIke Post",
175+
subTitle = "Click here to like post",
176+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
177+
)
178+
}
179+
)
180+
}
181+
Spacer(modifier = Modifier.width(10.dp))
182+
IconButton(onClick = { /*TODO*/ }) {
183+
Icon(
184+
imageVector = Icons.Default.Add,
185+
contentDescription = "add",
186+
modifier = Modifier
187+
.size(28.dp)
188+
.onGloballyPositioned {
189+
target["comment"] = ShowcaseProperty(
190+
index = 3,
191+
coordinates = it,
192+
title = "Comment button",
193+
subTitle = "Click here to add comment on post",
194+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
195+
)
196+
}
197+
)
198+
}
199+
Spacer(modifier = Modifier.width(8.dp))
200+
IconButton(onClick = { /*TODO*/ }) {
201+
Icon(
202+
imageVector = Icons.Filled.Share,
203+
contentDescription = "Share",
204+
modifier = Modifier
205+
.size(23.dp)
206+
.onGloballyPositioned {
207+
target["share"] = ShowcaseProperty(
208+
index = 4,
209+
coordinates = it,
210+
title = "Share button",
211+
subTitle = "Click here to Share post with others",
212+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
213+
)
214+
}
215+
)
216+
}
217+
}
218+
IconButton(modifier = Modifier
219+
.align(Alignment.CenterEnd),
220+
onClick = { /*TODO*/ }
221+
) {
222+
Icon(
223+
imageVector = Icons.Outlined.Star,
224+
contentDescription = "Save",
225+
modifier = Modifier
226+
.size(25.dp)
227+
.onGloballyPositioned {
228+
target["save"] = ShowcaseProperty(
229+
index = 5,
230+
coordinates = it,
231+
title = "Save button",
232+
subTitle = "Click here to save post",
233+
showCaseType = ShowcaseType.ANIMATED_RECTANGLE
234+
)
235+
}
236+
)
237+
}
15238
}
16239
}
17240
}
18241

19242
@Preview
20243
@Composable
21244
fun MainActivityPreview() {
22-
Text(text = "Hello World")
245+
Surface {
246+
ShowcaseExample()
247+
}
23248
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example.sscomposeshowcaseview
2+
3+
import com.example.sscomposeshowcaseview.R
4+
5+
object Data {
6+
var userList = listOf(
7+
Item(id = 1, profilePic = R.drawable.dp1, name = "Thomas")
8+
)
9+
}
10+
11+
data class Item(val id: Int, val profilePic: Int, val name: String)
127 KB
Loading
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="25dp"
3+
android:height="24.981703dp"
4+
android:viewportWidth="122.97"
5+
android:viewportHeight="122.88">
6+
<path
7+
android:fillColor="#FF000000"
8+
android:pathData="M61.44,0a61.46,61.46 0,0 1,54.91 89l6.44,25.74a5.83,5.83 0,0 1,-7.25 7L91.62,115A61.43,61.43 0,1 1,61.44 0ZM96.63,26.25a49.78,49.78 0,1 0,-9 77.52A5.83,5.83 0,0 1,92.4 103L109,107.77l-4.5,-18a5.86,5.86 0,0 1,0.51 -4.34,49.06 49.06,0 0,0 4.62,-11.58 50,50 0,0 0,-13 -47.62Z" />
9+
</vector>

sscomposeshowcaseview/build.gradle

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ android {
2727
kotlinOptions {
2828
jvmTarget = '1.8'
2929
}
30+
buildFeatures {
31+
compose true
32+
}
33+
composeOptions {
34+
kotlinCompilerExtensionVersion '1.1.1'
35+
}
3036
}
3137

3238
dependencies {
@@ -37,11 +43,16 @@ dependencies {
3743
testImplementation 'junit:junit:4.13.2'
3844
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
3945
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
46+
implementation "com.google.android.material:compose-theme-adapter:1.1.11"
47+
implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
48+
49+
//Compose
4050
implementation 'androidx.activity:activity-compose:1.4.0'
4151
implementation 'androidx.compose.material:material:1.1.1'
4252
implementation 'androidx.compose.animation:animation:1.1.1'
4353
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
4454
implementation 'androidx.compose.ui:ui-tooling:1.1.1'
45-
implementation "com.google.android.material:compose-theme-adapter:1.1.11"
46-
implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
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"
4758
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.example.sscomposeshowcaseview
2+
3+
import androidx.compose.ui.graphics.Color
4+
import androidx.compose.ui.layout.LayoutCoordinates
5+
6+
data class ShowcaseProperty(
7+
val index: Int,
8+
val coordinates: LayoutCoordinates,
9+
val title: String,
10+
val titleColor: Color = Color.White,
11+
val subTitle: String,
12+
val subTitleColor: Color = Color.White,
13+
val showCaseType: ShowcaseType = ShowcaseType.SIMPLE_ROUNDED
14+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example.sscomposeshowcaseview
2+
3+
/**
4+
* Select type of showcase
5+
*/
6+
enum class ShowcaseType {
7+
SIMPLE_ROUNDED,
8+
SIMPLE_RECTANGLE,
9+
ANIMATED_ROUNDED,
10+
ANIMATED_RECTANGLE
11+
}

0 commit comments

Comments
 (0)