├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── dynamislandview
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── dynamislandview
│ │ │ ├── DynamicIslandView.kt
│ │ │ ├── MainActivity.kt
│ │ │ └── ui
│ │ │ └── theme
│ │ │ ├── Color.kt
│ │ │ ├── Shape.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_close.xml
│ │ ├── ic_forward.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_pause.xml
│ │ ├── ic_rewind.xml
│ │ └── music_image.jpeg
│ │ ├── 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
│ │ ├── raw
│ │ ├── dynamic_island_motion
│ │ └── music_playing.json
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── dynamislandview
│ └── ExampleUnitTest.kt
├── art
└── dynamic_view.gif
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── settings.gradle
/.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 | gradlew
12 | gradlew.bat
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # compose-dynamic-spot-view
2 |
3 | Implemented dynamic spot view using jetpack compose and motion layout
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | }
5 |
6 | android {
7 | compileSdk 32
8 |
9 | defaultConfig {
10 | applicationId "com.example.myapplication"
11 | minSdk 21
12 | targetSdk 32
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | vectorDrawables {
18 | useSupportLibrary true
19 | }
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | compileOptions {
29 | sourceCompatibility JavaVersion.VERSION_1_8
30 | targetCompatibility JavaVersion.VERSION_1_8
31 | }
32 | kotlinOptions {
33 | jvmTarget = '1.8'
34 | }
35 | buildFeatures {
36 | compose true
37 | }
38 | composeOptions {
39 | kotlinCompilerExtensionVersion compose_version
40 | }
41 | packagingOptions {
42 | resources {
43 | excludes += '/META-INF/{AL2.0,LGPL2.1}'
44 | }
45 | }
46 | }
47 |
48 | dependencies {
49 |
50 | implementation 'androidx.core:core-ktx:1.7.0'
51 | implementation "androidx.compose.ui:ui:$compose_version"
52 | implementation "androidx.compose.material:material:$compose_version"
53 | implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
54 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
55 | implementation 'androidx.activity:activity-compose:1.3.1'
56 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
57 | testImplementation 'junit:junit:4.13.2'
58 | androidTestImplementation 'androidx.test.ext:junit:1.1.4'
59 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
60 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
61 | debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
62 | debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
63 | implementation ("com.airbnb.android:lottie-compose:4.0.0")
64 | implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha03")
65 |
66 |
67 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/dynamislandview/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.example.myapplication", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dynamislandview/DynamicIslandView.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview
2 |
3 | import androidx.compose.animation.core.LinearEasing
4 | import androidx.compose.animation.core.animateFloatAsState
5 | import androidx.compose.animation.core.tween
6 | import androidx.compose.foundation.Image
7 | import androidx.compose.foundation.background
8 | import androidx.compose.foundation.border
9 | import androidx.compose.foundation.clickable
10 | import androidx.compose.foundation.layout.*
11 | import androidx.compose.foundation.shape.CircleShape
12 | import androidx.compose.foundation.shape.RoundedCornerShape
13 | import androidx.compose.material.*
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.Share
16 | import androidx.compose.runtime.*
17 | import androidx.compose.ui.Alignment
18 | import androidx.compose.ui.Modifier
19 | import androidx.compose.ui.draw.clip
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.layout.ContentScale
22 | import androidx.compose.ui.layout.layoutId
23 | import androidx.compose.ui.platform.LocalContext
24 | import androidx.compose.ui.res.painterResource
25 | import androidx.compose.ui.text.SpanStyle
26 | import androidx.compose.ui.text.buildAnnotatedString
27 | import androidx.compose.ui.text.font.FontWeight
28 | import androidx.compose.ui.text.withStyle
29 | import androidx.compose.ui.unit.dp
30 | import androidx.compose.ui.unit.sp
31 | import androidx.constraintlayout.compose.ExperimentalMotionApi
32 | import androidx.constraintlayout.compose.MotionLayout
33 | import androidx.constraintlayout.compose.MotionScene
34 | import com.airbnb.lottie.compose.LottieAnimation
35 | import com.airbnb.lottie.compose.LottieCompositionSpec
36 | import com.airbnb.lottie.compose.animateLottieCompositionAsState
37 | import com.airbnb.lottie.compose.rememberLottieComposition
38 | import com.example.dynamislandview.ui.theme.Typography
39 |
40 | @OptIn(ExperimentalMotionApi::class)
41 | @Composable
42 | fun DynamicView() {
43 |
44 | val context = LocalContext.current
45 | val motionScene = remember {
46 | context.resources
47 | .openRawResource(R.raw.dynamic_island_motion)
48 | .readBytes()
49 | .decodeToString()
50 | }
51 |
52 | val shouldExpand = remember { mutableStateOf(false) }
53 | val motionProgress by animateFloatAsState(
54 | targetValue = if (shouldExpand.value) 1f else 0f,
55 | tween(250, easing = LinearEasing)
56 | )
57 | Box(
58 | modifier = Modifier
59 | .fillMaxSize()
60 | .background(MaterialTheme.colors.background),
61 | contentAlignment = Alignment.TopCenter
62 | ) {
63 | MotionLayout(
64 | motionScene = MotionScene(content = motionScene),
65 | progress = motionProgress,
66 | modifier = Modifier
67 | .fillMaxWidth()
68 | .wrapContentHeight(),
69 | ) {
70 | CollapsedMusicView(shouldExpand)
71 | ExpandedMusicView(shouldExpand)
72 |
73 | }
74 | }
75 | }
76 |
77 | @Composable
78 | fun CollapsedMusicView(shouldExpand: MutableState) {
79 | val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.music_playing))
80 | val progress by animateLottieCompositionAsState(
81 | composition,
82 | isPlaying = true,
83 | restartOnPlay = true,
84 | iterations = Integer.MAX_VALUE
85 | )
86 | Card(
87 | Modifier
88 | .layoutId("collapsed_card")
89 | .wrapContentWidth()
90 | .wrapContentHeight()
91 | .clickable {
92 | shouldExpand.value = true
93 | },
94 | backgroundColor = Color.Black,
95 | shape = RoundedCornerShape(24.dp)
96 | ) {
97 | Row(
98 | modifier = Modifier
99 | .wrapContentWidth()
100 | .wrapContentHeight()
101 | .padding(horizontal = 12.dp, vertical = 8.dp),
102 | verticalAlignment = Alignment.CenterVertically,
103 | horizontalArrangement = Arrangement.SpaceBetween
104 | ) {
105 | Image(
106 | painter = painterResource(R.drawable.music_image),
107 | contentDescription = "avatar",
108 | contentScale = ContentScale.Crop, // crop the image if it's not a square
109 | modifier = Modifier
110 | .size(28.dp)
111 | .clip(CircleShape) // clip to the circle shape
112 | .border(2.dp, Color.LightGray, CircleShape) // add a border (optional)
113 | )
114 | Text(
115 | text = "Gunehgar",
116 | color = Color.White,
117 | fontWeight = FontWeight.SemiBold,
118 | fontSize = 18.sp,
119 | modifier = Modifier.padding(start = 8.dp),
120 | maxLines = 1
121 |
122 | )
123 | LottieAnimation(
124 | composition = composition,
125 | progress = progress,
126 | modifier = Modifier
127 | .size(28.dp)
128 | .padding(start = 12.dp)
129 | )
130 | }
131 | }
132 | }
133 |
134 | @Composable
135 | fun ExpandedMusicView(shouldExpand: MutableState) {
136 |
137 | val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.music_playing))
138 | val progress by animateLottieCompositionAsState(
139 | composition,
140 | isPlaying = true,
141 | restartOnPlay = true,
142 | iterations = Integer.MAX_VALUE
143 | )
144 | Card(
145 | Modifier
146 | .layoutId("expanded_card")
147 | .fillMaxWidth()
148 | .wrapContentHeight()
149 | .padding(16.dp)
150 | .clickable {
151 | shouldExpand.value = false
152 | },
153 | backgroundColor = Color.Black,
154 | shape = RoundedCornerShape(24.dp)
155 | ) {
156 | Column(
157 | Modifier
158 | .fillMaxWidth()
159 | .wrapContentHeight()
160 | .padding(16.dp)
161 | ) {
162 | Row(
163 | modifier = Modifier
164 | .fillMaxWidth()
165 | .wrapContentHeight(),
166 | verticalAlignment = Alignment.CenterVertically,
167 | horizontalArrangement = Arrangement.SpaceBetween
168 | ) {
169 | Image(
170 | painter = painterResource(R.drawable.music_image),
171 | contentDescription = "avatar",
172 | contentScale = ContentScale.Crop, // crop the image if it's not a square
173 | modifier = Modifier
174 | .size(64.dp)
175 | .clip(CircleShape) // clip to the circle shape
176 | .border(2.dp, Color.LightGray, CircleShape) // add a border (optional)
177 | )
178 | Text(
179 | text = buildAnnotatedString {
180 | withStyle(
181 | style = SpanStyle(
182 | color = Color.White,
183 | fontSize = 24.sp,
184 | fontWeight = FontWeight.SemiBold
185 | )
186 | ) {
187 | append("Gunehgar")
188 | }
189 | withStyle(
190 | style = SpanStyle(
191 | color = Color.White,
192 | fontSize = 18.sp,
193 | fontWeight = FontWeight.Normal
194 | )
195 | ) {
196 | append("\nBy Divine")
197 | }
198 | },
199 | color = Color.White,
200 | fontWeight = FontWeight.SemiBold,
201 | fontSize = 24.sp,
202 | modifier = Modifier.padding(end = 102.dp)
203 | )
204 | LottieAnimation(
205 | composition = composition,
206 | progress = progress,
207 | modifier = Modifier.size(36.dp),
208 | )
209 | }
210 | Spacer(
211 | modifier = Modifier
212 | .fillMaxWidth()
213 | .height(12.dp)
214 | )
215 | Row(
216 | Modifier.fillMaxWidth(),
217 | verticalAlignment = Alignment.CenterVertically,
218 | horizontalArrangement = Arrangement.SpaceEvenly
219 | ) {
220 | Text(
221 | text = "01:31",
222 | style = Typography.body1,
223 | color = Color.White,
224 | modifier = Modifier.weight(0.125f)
225 | )
226 | LinearProgressIndicator(
227 | progress = 0.5f,
228 | color = Color.White,
229 | backgroundColor = Color.Gray,
230 | modifier = Modifier
231 | .weight(0.65f)
232 | .height(8.dp)
233 | .clip(RoundedCornerShape(8.dp))
234 | )
235 | Text(
236 | text = "03:05",
237 | style = Typography.body1,
238 | color = Color.White,
239 | modifier = Modifier
240 | .weight(0.125f)
241 | .padding(start = 4.dp)
242 | )
243 | }
244 |
245 | Spacer(
246 | modifier = Modifier
247 | .fillMaxWidth()
248 | .height(16.dp)
249 | )
250 | Row(
251 | modifier = Modifier
252 | .fillMaxWidth(),
253 | verticalAlignment = Alignment.CenterVertically,
254 | horizontalArrangement = Arrangement.SpaceBetween
255 | ) {
256 | Icon(
257 | imageVector = Icons.Filled.Share,
258 | contentDescription = "share icon",
259 | tint = Color.White
260 | )
261 | Icon(
262 | painter = painterResource(id = R.drawable.ic_rewind),
263 | tint = Color.White,
264 | modifier = Modifier.padding(start = 48.dp),
265 | contentDescription = "rewind icon"
266 | )
267 | Icon(
268 | painter = painterResource(id = R.drawable.ic_pause),
269 | tint = Color.White,
270 | contentDescription = "play icon"
271 | )
272 | Icon(
273 | painter = painterResource(id = R.drawable.ic_forward),
274 | tint = Color.White,
275 | modifier = Modifier.padding(end = 48.dp),
276 | contentDescription = "forward icon"
277 | )
278 | Icon(
279 | painter = painterResource(id = R.drawable.ic_close),
280 | tint = Color.White,
281 | contentDescription = "close icon"
282 | )
283 | }
284 | }
285 | }
286 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dynamislandview/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.constraintlayout.compose.ExperimentalMotionApi
7 | import com.example.dynamislandview.ui.theme.MyApplicationTheme
8 |
9 | @OptIn(ExperimentalMotionApi::class)
10 | class MainActivity : ComponentActivity() {
11 | override fun onCreate(savedInstanceState: Bundle?) {
12 | super.onCreate(savedInstanceState)
13 | setContent {
14 | MyApplicationTheme {
15 | DynamicView()
16 | }
17 | }
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dynamislandview/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple200 = Color(0xFFBB86FC)
6 | val Purple500 = Color(0xFF6200EE)
7 | val Purple700 = Color(0xFF3700B3)
8 | val Teal200 = Color(0xFF03DAC5)
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dynamislandview/ui/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview.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/example/dynamislandview/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview.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 = Purple200,
11 | primaryVariant = Purple700,
12 | secondary = Teal200
13 | )
14 |
15 | private val LightColorPalette = lightColors(
16 | primary = Purple500,
17 | primaryVariant = Purple700,
18 | secondary = Teal200
19 |
20 | /* Other default colors to override
21 | background = Color.White,
22 | surface = Color.White,
23 | onPrimary = Color.White,
24 | onSecondary = Color.Black,
25 | onBackground = Color.Black,
26 | onSurface = Color.Black,
27 | */
28 | )
29 |
30 | @Composable
31 | fun MyApplicationTheme(
32 | darkTheme: Boolean = isSystemInDarkTheme(),
33 | content: @Composable () -> Unit
34 | ) {
35 | val colors = if (darkTheme) {
36 | DarkColorPalette
37 | } else {
38 | LightColorPalette
39 | }
40 |
41 | MaterialTheme(
42 | colors = colors,
43 | typography = Typography,
44 | shapes = Shapes,
45 | content = content
46 | )
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dynamislandview/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview.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/ic_close.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_forward.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/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/ic_pause.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rewind.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/music_image.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/drawable/music_image.jpeg
--------------------------------------------------------------------------------
/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/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw/dynamic_island_motion:
--------------------------------------------------------------------------------
1 | {
2 | ConstraintSets: {
3 | start: {
4 | collapsed_card: {
5 | width: 'spread',
6 | height: 56,
7 | start: ['parent', 'start'],
8 | end: ['parent', 'end'],
9 | top: ['parent','top'],
10 | bottom: ['parent','bottom'],
11 | visibility : 'visible',
12 |
13 | },
14 | expanded_card : {
15 | width: 'spread',
16 | height: 'spread',
17 | start: ['parent', 'start'],
18 | end: ['parent', 'end'],
19 | top: ['parent','top'],
20 | bottom: ['parent','bottom'],
21 | visibility : 'gone'
22 | }
23 | },
24 | end: {
25 | collapsed_card: {
26 | width: 'spread',
27 | height: 'spread',
28 | start: ['parent', 'start'],
29 | end: ['parent', 'end'],
30 | top: ['parent','top'],
31 | bottom: ['parent','bottom'],
32 | visibility : 'gone'
33 |
34 | }
35 | expanded_card : {
36 | width: 'spread',
37 | height: 250,
38 | start: ['parent', 'start'],
39 | end: ['parent', 'end'],
40 | top: ['parent','top'],
41 | bottom: ['parent','bottom'],
42 | visibility : 'visible'
43 | }
44 | }
45 | }
46 |
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/raw/music_playing.json:
--------------------------------------------------------------------------------
1 | {"v":"5.5.8","fr":30,"ip":0,"op":60,"w":128,"h":128,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[102.49999999999999,113.99999999999999,0],"ix":2},"a":{"a":0,"k":[0,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.665,"y":1},"o":{"x":0.088,"y":0},"t":0,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-8.75],[10,45],[5,50],[-5,50],[-10,45],[-10,-8.75],[-5,-13.75],[5,-13.75]],"c":true}]},{"i":{"x":0.888,"y":0.992},"o":{"x":0.315,"y":0},"t":15,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-29.5],[10,45],[5,50],[-5,50],[-10,45],[-10,-29.5],[-5,-34.5],[5,-34.5]],"c":true}]},{"i":{"x":0.777,"y":1},"o":{"x":0.117,"y":0.013},"t":30,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-8.75],[10,45],[5,50],[-5,50],[-10,45],[-10,-8.75],[-5,-13.75],[5,-13.75]],"c":true}]},{"i":{"x":0.853,"y":1},"o":{"x":0.098,"y":0},"t":46,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,18.75],[10,45],[5,50],[-5,50],[-10,45],[-10,18.75],[-5,13.75],[5,13.75]],"c":true}]},{"t":60,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-8.75],[10,45],[5,50],[-5,50],[-10,45],[-10,-8.75],[-5,-13.75],[5,-13.75]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9568627450980393,0.9411764705882353,0.9568627450980393,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":61,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[62.5,113.99999999999999,0],"ix":2},"a":{"a":0,"k":[0,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.631,"y":1},"o":{"x":0.167,"y":0},"t":0,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-33],[10,45],[5,50],[-5,50],[-10,45],[-10,-33],[-5,-38],[5,-38]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.391,"y":0},"t":13.846,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,4],[10,45],[5,50],[-5,50],[-10,45],[-10,4],[-5,-1],[5,-1]],"c":true}]},{"i":{"x":0.88,"y":1},"o":{"x":0.093,"y":0},"t":27,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-33],[10,45],[5,50],[-5,50],[-10,45],[-10,-33],[-5,-38],[5,-38]],"c":true}]},{"i":{"x":0.873,"y":1},"o":{"x":0.165,"y":0},"t":45,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,11.875],[10,45],[5,50],[-5,50],[-10,45],[-10,11.875],[-5,6.875],[5,6.875]],"c":true}]},{"t":60,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,-33],[10,45],[5,50],[-5,50],[-10,45],[-10,-33],[-5,-38],[5,-38]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9568627450980393,0.9411764705882353,0.9568627450980393,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":61,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22.5,113.99999999999999,0],"ix":2},"a":{"a":0,"k":[0,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.562,"y":1},"o":{"x":0.46,"y":0},"t":0,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,29.25],[10,45],[5,50],[-5,50],[-10,45],[-10,29.25],[-5,24.25],[5,24.25]],"c":true}]},{"i":{"x":0.505,"y":1},"o":{"x":0.402,"y":0},"t":15,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,13],[10,45],[5,50],[-5,50],[-10,45],[-10,13],[-5,8],[5,8]],"c":true}]},{"i":{"x":0.407,"y":1},"o":{"x":0.167,"y":0},"t":32,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,29.25],[10,45],[5,50],[-5,50],[-10,45],[-10,29.25],[-5,24.25],[5,24.25]],"c":true}]},{"i":{"x":0.599,"y":1},"o":{"x":0.526,"y":0},"t":47,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,3],[10,45],[5,50],[-5,50],[-10,45],[-10,3],[-5,-2],[5,-2]],"c":true}]},{"t":60,"s":[{"i":[[0,-2.761],[0,0],[2.761,0],[0,0],[0,2.761],[0,0],[-2.761,0],[0,0]],"o":[[0,0],[0,2.761],[0,0],[-2.761,0],[0,0],[0,-2.761],[0,0],[2.761,0]],"v":[[10,29.25],[10,45],[5,50],[-5,50],[-10,45],[-10,29.25],[-5,24.25],[5,24.25]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.9568627450980393,0.9411764705882353,0.9568627450980393,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":61,"st":0,"bm":0}],"markers":[]}
--------------------------------------------------------------------------------
/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 | My Application
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/dynamislandview/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.dynamislandview
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/art/dynamic_view.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/art/dynamic_view.gif
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | compose_version = '1.1.0-beta01'
4 | }
5 | }// Top-level build file where you can add configuration options common to all sub-projects/modules.
6 | plugins {
7 | id 'com.android.application' version '7.2.2' apply false
8 | id 'com.android.library' version '7.2.2' apply false
9 | id 'org.jetbrains.kotlin.android' version '1.5.31' apply false
10 | }
11 |
12 | task clean(type: Delete) {
13 | delete rootProject.buildDir
14 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satyajeet4047/compose-dynamic-spot-view/89e316144100b2b40d139f02d44a2936a6ba5bc9/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Nov 26 21:57:03 IST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "My Application"
16 | include ':app'
17 |
--------------------------------------------------------------------------------