├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mobile
│ │ └── app
│ │ └── sporting
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mobile
│ │ │ └── app
│ │ │ └── sporting
│ │ │ ├── HomeFooter.kt
│ │ │ ├── HomeScreen.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── SelectionDetails.kt
│ │ │ ├── linegraph
│ │ │ ├── GraphView.kt
│ │ │ └── LineChartData.kt
│ │ │ └── ui
│ │ │ ├── Color.kt
│ │ │ ├── ModifiersExt.kt
│ │ │ ├── Shape.kt
│ │ │ ├── Theme.kt
│ │ │ ├── Type.kt
│ │ │ └── transitions.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── pokeball.png
│ │ ├── surfer_four.jpg
│ │ ├── surfer_one.jpg
│ │ ├── surfer_three.jpg
│ │ └── surfer_two.jpg
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ └── test
│ └── java
│ └── com
│ └── mobile
│ └── app
│ └── sporting
│ └── ExampleUnitTest.kt
├── build.gradle
├── docs
└── dribbble_sport.gif
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea/
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sporting
2 | WIP implementation of this dribble shot https://dribbble.com/shots/6215241-Sport-activity-dashboard-application/attachments/6215241?mode=media in Jetpack compose
3 |
4 | 
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdkVersion 30
8 |
9 | defaultConfig {
10 | applicationId "com.mobile.app.sporting"
11 | minSdkVersion 21
12 | targetSdkVersion 30
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_1_8
27 | targetCompatibility JavaVersion.VERSION_1_8
28 | }
29 | kotlinOptions {
30 | jvmTarget = '1.8'
31 | useIR = true
32 | }
33 | buildFeatures {
34 | compose true
35 | }
36 | composeOptions {
37 | kotlinCompilerExtensionVersion compose_version
38 | kotlinCompilerVersion '1.4.20'
39 | }
40 | }
41 |
42 | dependencies {
43 | def nav_compose_version = "1.0.0-alpha03"
44 | implementation "androidx.navigation:navigation-compose:$nav_compose_version"
45 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
46 | implementation 'androidx.core:core-ktx:1.3.2'
47 | implementation 'androidx.appcompat:appcompat:1.2.0'
48 | implementation 'com.google.android.material:material:1.2.1'
49 | implementation "androidx.compose.ui:ui:$compose_version"
50 | implementation "androidx.compose.material:material:$compose_version"
51 | implementation "androidx.compose.material:material-icons-extended:$compose_version"
52 | implementation "androidx.compose.ui:ui-tooling:$compose_version"
53 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01'
54 | implementation "dev.chrisbanes.accompanist:accompanist-coil:0.3.3.1"
55 | testImplementation 'junit:junit:4.+'
56 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
57 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
58 | }
--------------------------------------------------------------------------------
/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/mobile/app/sporting/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
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.mobile.app.sporting", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/HomeFooter.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
2 |
3 | import androidx.compose.animation.animatedFloat
4 | import androidx.compose.animation.core.tween
5 | import androidx.compose.foundation.Image
6 | import androidx.compose.foundation.ScrollableRow
7 | import androidx.compose.foundation.background
8 | import androidx.compose.foundation.layout.*
9 | import androidx.compose.foundation.shape.RoundedCornerShape
10 | import androidx.compose.material.MaterialTheme
11 | import androidx.compose.material.Surface
12 | import androidx.compose.material.Text
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.runtime.onActive
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.drawLayer
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.platform.DensityAmbient
19 | import androidx.compose.ui.res.imageResource
20 | import androidx.compose.ui.text.font.FontWeight
21 | import androidx.compose.ui.unit.dp
22 | import androidx.compose.ui.unit.sp
23 |
24 | val mockSurfers = listOf(
25 | R.drawable.surfer_one,
26 | R.drawable.surfer_two,
27 | R.drawable.surfer_three,
28 | R.drawable.surfer_four
29 | )
30 |
31 | @Composable
32 | fun Footer(
33 | modifier: Modifier = Modifier,
34 | surfers: List = mockSurfers,
35 | ) {
36 | Column(
37 | modifier
38 | .background(shape = RoundedCornerShape(topRight = 64.dp), color = Color(0xffff0151))
39 | .padding(vertical = 24.dp)
40 | .padding(start = 24.dp)
41 | .preferredHeight(180.dp)
42 | ) {
43 | Box {
44 | val t = animatedFloat(initVal = 1f)
45 | val t2 = animatedFloat(initVal = 1f)
46 | val density = DensityAmbient.current
47 |
48 | onActive {
49 | t.animateTo(0f, tween(durationMillis = 800))
50 | t2.animateTo(0f, tween(durationMillis = 1000))
51 | }
52 |
53 | Text(
54 | text = "Rental equipment",
55 | style = MaterialTheme.typography.h4.copy(
56 | fontWeight = FontWeight.Bold,
57 | fontSize = 38.sp,
58 | letterSpacing = 1.5.sp
59 | ),
60 | color = Color(0xFFf0004c),
61 | modifier = Modifier.drawLayer(translationX = with(density) { 240.dp.toPx() * t2.value })
62 | )
63 |
64 | Text(
65 | text = "Rental equipment",
66 | color = Color.White,
67 | style = MaterialTheme.typography.h5.copy(fontWeight = FontWeight.Bold),
68 | modifier = Modifier.drawLayer(
69 | translationX = with(density) { -128.dp.toPx() * t.value }
70 | )
71 | )
72 | }
73 |
74 | Spacer(modifier = Modifier.height(8.dp))
75 | ScrollableRow {
76 | surfers.forEach { surfer ->
77 | Surface(
78 | shape = RoundedCornerShape(16.dp)
79 | ) {
80 | Image(
81 | bitmap = imageResource(id = surfer),
82 | modifier = Modifier.size(140.dp)
83 | )
84 | }
85 |
86 | Spacer(modifier = Modifier.width(8.dp))
87 | }
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/HomeScreen.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
2 |
3 | import androidx.compose.animation.*
4 | import androidx.compose.animation.core.LinearOutSlowInEasing
5 | import androidx.compose.animation.core.tween
6 | import androidx.compose.foundation.ScrollableColumn
7 | import androidx.compose.foundation.background
8 | import androidx.compose.foundation.clickable
9 | import androidx.compose.foundation.layout.*
10 | import androidx.compose.foundation.shape.CircleShape
11 | import androidx.compose.foundation.shape.RoundedCornerShape
12 | import androidx.compose.material.*
13 | import androidx.compose.material.icons.Icons
14 | import androidx.compose.material.icons.filled.Add
15 | import androidx.compose.material.icons.outlined.CalendarToday
16 | import androidx.compose.material.icons.outlined.Person
17 | import androidx.compose.runtime.*
18 | import androidx.compose.ui.Alignment
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.draw.scale
21 | import androidx.compose.ui.drawLayer
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.graphics.TransformOrigin
24 | import androidx.compose.ui.graphics.graphicsLayer
25 | import androidx.compose.ui.platform.DensityAmbient
26 | import androidx.compose.ui.text.TextStyle
27 | import androidx.compose.ui.text.font.FontWeight
28 | import androidx.compose.ui.text.style.TextAlign
29 | import androidx.compose.ui.unit.dp
30 | import androidx.compose.ui.unit.sp
31 | import androidx.navigation.NavController
32 | import androidx.navigation.compose.navigate
33 | import com.mobile.app.sporting.ui.*
34 |
35 | @Composable
36 | @ExperimentalAnimationApi
37 | fun HomeScreen(navController: NavController) {
38 | var selectedIndex by remember { mutableStateOf(0) }
39 | var visibility by remember { mutableStateOf(false) }
40 |
41 | SideEffect {
42 | visibility = true
43 | }
44 |
45 | Box(
46 | Modifier.fillMaxSize()
47 | ) {
48 | ScrollableColumn(
49 | Modifier.fillMaxSize()
50 | .background(color = Color(0xfff8f9f8))
51 | .padding(horizontal = 16.dp)
52 | ) {
53 | val ratingTransition = transition(
54 | definition = ratingTransDef,
55 | toState = "end",
56 | initState = "start"
57 | )
58 | Text(
59 | text = "Rating",
60 | color = Color(0xffcbcccb),
61 | style = MaterialTheme.typography.h6,
62 | modifier = Modifier.padding(top = 24.dp)
63 | .offset(y = ratingTransition[ratingOffset])
64 | )
65 |
66 | val topActTransition = transition(
67 | definition = topActivityTransDef,
68 | toState = "end",
69 | initState = "start"
70 | )
71 | Row(
72 | Modifier.fillMaxWidth()
73 | .offset(y = topActTransition[topActivityOffset]),
74 | verticalAlignment = Alignment.CenterVertically
75 | ) {
76 | Text(
77 | text = "Top Activity",
78 | color = Color(0xff2f2e38),
79 | style = MaterialTheme.typography.h4.copy(fontWeight = FontWeight.Bold),
80 | modifier = Modifier.weight(1f)
81 | )
82 |
83 | Icon(
84 | Icons.Outlined.CalendarToday,
85 | tint = Color(0xff2f2e38)
86 | )
87 | }
88 |
89 | Spacer(modifier = Modifier.height(48.dp))
90 |
91 | Row(
92 | modifier = Modifier.fillMaxWidth(),
93 | horizontalArrangement = Arrangement.SpaceAround,
94 | verticalAlignment = Alignment.CenterVertically
95 | ) {
96 | listOf("Surfing", "Snowboard", "Skiing").forEachIndexed { index, title ->
97 | if (index == selectedIndex) {
98 | SelectedChip(label = title)
99 | } else {
100 | UnselectedChip(
101 | label = title,
102 | index = index,
103 | onSelectedIndexChange = { selectedIndex = it }
104 | )
105 | }
106 | }
107 | }
108 |
109 | Spacer(modifier = Modifier.preferredHeight(32.dp))
110 |
111 | Row(
112 | Modifier.fillMaxWidth(),
113 | verticalAlignment = Alignment.CenterVertically,
114 | horizontalArrangement = Arrangement.SpaceBetween
115 | ) {
116 | Column(
117 | //Modifier.weight(1f)
118 | ) {
119 | val state = transition(
120 | definition = textValueTransDef,
121 | toState = "end",
122 | initState = "start"
123 | )
124 | val text = String.format("%.3f", state[propKey])
125 | Text(
126 | text = text,
127 | color = Color(0xff2f2e38),
128 | style = MaterialTheme.typography.h4.copy(fontWeight = FontWeight.Bold)
129 | )
130 |
131 | Text(
132 | text = "activity",
133 | color = Color(0xffcbcccb)
134 | )
135 | }
136 |
137 | Row {
138 | AnimatedVisibility(
139 | visible = visibility,
140 | enter = expandHorizontally(
141 | expandFrom = Alignment.End,
142 | animSpec = tween(durationMillis = 400)
143 | )
144 | + fadeIn(animSpec = tween(durationMillis = 1200))
145 | ) {
146 | Text(
147 | text = "profile",
148 | color = Color(0xff2f2e38),
149 | style = TextStyle(
150 | fontWeight = FontWeight.W600,
151 | fontSize = 18.sp,
152 | letterSpacing = 1.sp
153 | )
154 | )
155 | }
156 | Spacer(modifier = Modifier.preferredWidth(6.dp))
157 | Icon(Icons.Outlined.Person, tint = Color(0xff2f2e38))
158 | }
159 | }
160 | Spacer(modifier = Modifier.height(16.dp))
161 | WeeklyChart(modifier = Modifier.align(Alignment.CenterHorizontally))
162 | Spacer(modifier = Modifier.preferredHeight(32.dp))
163 | PeriodRow(navController)
164 | Spacer(modifier = Modifier.preferredHeight(48.dp))
165 | }
166 |
167 | Footer(
168 | modifier = Modifier
169 | .fillMaxWidth()
170 | .align(Alignment.BottomCenter)
171 | )
172 | }
173 | }
174 |
175 | @Composable
176 | @ExperimentalAnimationApi
177 | fun UnselectedChip(
178 | label: String,
179 | index: Int,
180 | onSelectedIndexChange: (Int) -> Unit
181 | ) {
182 | var visibility by remember { mutableStateOf(false) }
183 | SideEffect {
184 | visibility = true
185 | }
186 | AnimatedVisibility(
187 | visible = visibility,
188 | enter = fadeIn(
189 | animSpec = tween(durationMillis = 200)
190 | ) + expandHorizontally(
191 | expandFrom = Alignment.End,
192 | animSpec = tween(durationMillis = 400)
193 | )
194 | ) {
195 | Text(
196 | text = label,
197 | color = Color(0xffcbcccb),
198 | textAlign = TextAlign.Center,
199 | fontSize = 18.sp,
200 | fontWeight = FontWeight.Bold,
201 | modifier = Modifier
202 | .clickable(onClick = { onSelectedIndexChange(index) })
203 | )
204 | }
205 | }
206 |
207 | @Composable
208 | @ExperimentalAnimationApi
209 | fun SelectedChip(label: String) {
210 | Surface(
211 | shape = RoundedCornerShape(16.dp),
212 | color = Color(0xffffbd00),
213 | modifier = Modifier,
214 | elevation = 4.dp,
215 | ) {
216 | Text(
217 | text = label,
218 | textAlign = TextAlign.Center,
219 | color = Color.White,
220 | fontWeight = FontWeight.Bold,
221 | modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
222 | )
223 | }
224 | }
225 |
226 | @Composable
227 | fun WeeklyChart(modifier: Modifier = Modifier) {
228 | val transition = transition(
229 | definition = weekChartTransitionDef,
230 | toState = "end",
231 | initState = "start"
232 | )
233 |
234 | Surface(
235 | shape = RoundedCornerShape(16.dp),
236 | color = Color(0xFFfefffe),
237 | modifier = modifier.fillMaxWidth(0.95f)
238 | .preferredHeight(180.dp)
239 | .graphicsLayer(
240 | cameraDistance = 40f,
241 | rotationX = transition[rotationX],
242 | transformOrigin = TransformOrigin(1.0f, 1.0f)
243 | ),
244 | elevation = 4.dp
245 | ) {
246 | Row(
247 | modifier = Modifier.fillMaxWidth()
248 | .padding(horizontal = 16.dp),
249 | verticalAlignment = Alignment.CenterVertically,
250 | horizontalArrangement = Arrangement.SpaceBetween
251 | ) {
252 | dayBarItems.forEach { DayBarItem(day = it.day, level = it.level) }
253 | }
254 | }
255 | }
256 |
257 | @Composable
258 | fun DayBarItem(day: String, level: Float) {
259 | Column(
260 | verticalArrangement = Arrangement.Center,
261 | horizontalAlignment = Alignment.CenterHorizontally
262 | ) {
263 | val high = level >= 0.7f
264 | val textColor = animatedColor(initVal = lowDayTextColor)
265 | val bgColor = if (high) dayBarHigh else dayBarLow
266 |
267 | Text(
268 | text = day,
269 | color = textColor.value,
270 | fontWeight = if (high) FontWeight.W500 else FontWeight.Normal
271 | )
272 | Spacer(modifier = Modifier.height(10.dp))
273 | LevelBar(load = level, bgColor = weekBarBgColor, fillColor = bgColor)
274 |
275 | if (high) textColor.animateTo(highDayTextColor, tween(durationMillis = 150))
276 | }
277 | }
278 |
279 | @Composable
280 | fun LevelBar(
281 | load: Float,
282 | bgColor: Color,
283 | fillColor: Color,
284 | modifier: Modifier = Modifier
285 | ) {
286 |
287 | val state = transition(
288 | definition = barLoadTransitionDef,
289 | toState = 2,
290 | initState = 1
291 | )
292 |
293 | val multiplier = if (state[barLoadPropKey] >= load) {
294 | state[barLoadPropKey]
295 | } else {
296 | load
297 | }
298 | val height = (multiplier) * with(DensityAmbient.current) { 120.dp.toIntPx() }
299 |
300 | Box(
301 | modifier = Modifier
302 | .background(color = bgColor, shape = RoundedCornerShape(3.dp))
303 | ) {
304 | Spacer(modifier.width(6.dp).height(120.dp))
305 | Spacer(
306 | modifier = modifier
307 | .width(6.dp)
308 | .height(with(DensityAmbient.current) { height.toDp() })
309 | .background(color = fillColor, shape = RoundedCornerShape(3.dp))
310 | .align(Alignment.BottomCenter)
311 | )
312 | }
313 | }
314 |
315 | @Composable
316 | fun PeriodRow(navController: NavController) {
317 | Row(
318 | Modifier.fillMaxWidth().padding(horizontal = 16.dp),
319 | horizontalArrangement = Arrangement.SpaceBetween,
320 | verticalAlignment = Alignment.CenterVertically
321 | ) {
322 | Period(label = "Day")
323 | Period(label = "Week", isSelected = true, delay = 250)
324 | Period(label = "Month", delay = 550)
325 | IconButton(onClick = { navController.navigate("details") }) {
326 | val state = transition(
327 | definition = iconTransitionDefinition,
328 | toState = 2,
329 | initState = 1,
330 | )
331 | val icp = state[iconProp]
332 |
333 | Box(
334 | modifier = Modifier.size(64.dp)
335 | .background(color = Color(0xff2f2e38), shape = CircleShape)
336 | .scale(icp),
337 | contentAlignment = Alignment.Center
338 | ) {
339 | Icon(Icons.Default.Add)
340 | }
341 | }
342 | }
343 | }
344 |
345 | @Composable
346 | fun Period(
347 | label: String,
348 | modifier: Modifier = Modifier,
349 | isSelected: Boolean = false,
350 | delay: Int = 0
351 | ) {
352 | val animController = animatedFloat(initVal = 1f)
353 | onActive {
354 | animController.animateTo(
355 | 0f,
356 | tween(durationMillis = 400 + delay, easing = LinearOutSlowInEasing)
357 | )
358 | }
359 |
360 | Column(
361 | modifier = modifier
362 | .drawLayer(translationY = with(DensityAmbient.current) { -48.dp.toPx() } * animController.value),
363 | horizontalAlignment = Alignment.CenterHorizontally,
364 | ) {
365 | Text(
366 | text = label,
367 | fontSize = 16.sp,
368 | fontWeight = if (isSelected) FontWeight.W600 else FontWeight.Normal,
369 | color = if (isSelected) Color(0xff2f2e38) else Color(0xffcbcccb)
370 | )
371 | Spacer(modifier = Modifier.height(4.dp))
372 | Box(
373 | modifier = Modifier.size(8.dp)
374 | .background(
375 | color = if (isSelected) Color(0xff2f2e38) else Color.Transparent,
376 | shape = CircleShape
377 | ),
378 | )
379 | }
380 | }
381 |
382 | data class DayBarData(val day: String, val level: Float)
383 |
384 | val dayBarItems = listOf(
385 | DayBarData(day = "Mo", level = 0.2f),
386 | DayBarData(day = "Tu", level = 0.2f),
387 | DayBarData(day = "We", level = 0.9f),
388 | DayBarData(day = "Th", level = 0.3f),
389 | DayBarData(day = "Fr", level = 0.4f),
390 | DayBarData(day = "Sa", level = 0.5f),
391 | DayBarData(day = "Su", level = 0.7f),
392 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import androidx.compose.animation.ExperimentalAnimationApi
6 | import androidx.compose.material.MaterialTheme
7 | import androidx.compose.material.Surface
8 | import androidx.compose.ui.platform.setContent
9 | import androidx.navigation.compose.NavHost
10 | import androidx.navigation.compose.composable
11 | import androidx.navigation.compose.rememberNavController
12 | import com.mobile.app.sporting.ui.SportingTheme
13 |
14 | @ExperimentalAnimationApi
15 | class MainActivity : AppCompatActivity() {
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 |
19 | setContent {
20 | SportingTheme {
21 | val navController = rememberNavController()
22 |
23 | NavHost(navController = navController, startDestination = "home") {
24 | composable("home") {
25 | Surface(color = MaterialTheme.colors.background) {
26 | HomeScreen(navController)
27 | }
28 | }
29 | composable("details") { SelectionDetails(navController) }
30 | }
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/SelectionDetails.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
2 |
3 | import androidx.compose.animation.*
4 | import androidx.compose.animation.core.tween
5 | import androidx.compose.foundation.background
6 | import androidx.compose.foundation.clickable
7 | import androidx.compose.foundation.layout.*
8 | import androidx.compose.foundation.shape.CircleShape
9 | import androidx.compose.foundation.shape.RoundedCornerShape
10 | import androidx.compose.material.Icon
11 | import androidx.compose.material.IconButton
12 | import androidx.compose.material.Surface
13 | import androidx.compose.material.Text
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.ArrowBack
16 | import androidx.compose.material.icons.filled.KeyboardArrowRight
17 | import androidx.compose.material.icons.filled.Star
18 | import androidx.compose.runtime.*
19 | import androidx.compose.ui.Alignment
20 | import androidx.compose.ui.Modifier
21 | import androidx.compose.ui.draw.clip
22 | import androidx.compose.ui.drawBehind
23 | import androidx.compose.ui.drawLayer
24 | import androidx.compose.ui.geometry.Offset
25 | import androidx.compose.ui.geometry.Rect
26 | import androidx.compose.ui.graphics.Color
27 | import androidx.compose.ui.graphics.Paint
28 | import androidx.compose.ui.graphics.RectangleShape
29 | import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
30 | import androidx.compose.ui.platform.DensityAmbient
31 | import androidx.compose.ui.text.font.FontWeight
32 | import androidx.compose.ui.text.style.TextDecoration
33 | import androidx.compose.ui.unit.Dp
34 | import androidx.compose.ui.unit.dp
35 | import androidx.compose.ui.unit.lerp
36 | import androidx.compose.ui.unit.sp
37 | import androidx.navigation.NavController
38 | import com.mobile.app.sporting.ui.*
39 | import dev.chrisbanes.accompanist.coil.CoilImage
40 | import kotlinx.coroutines.delay
41 |
42 | @Composable
43 | @ExperimentalAnimationApi
44 | fun SelectionDetails(navController: NavController) {
45 | Box(modifier = Modifier.fillMaxSize()) {
46 | ConstraintLayout(
47 | modifier = Modifier.fillMaxSize()
48 | .background(color = surfaceColor)
49 | ) {
50 | val (
51 | headerRef,
52 | buttonRef,
53 | gapRef,
54 | itemsRef) = createRefs()
55 |
56 | Header(modifier = Modifier.constrainAs(headerRef) {
57 | top.linkTo(parent.top)
58 | start.linkTo(parent.start)
59 | end.linkTo(parent.end)
60 | }, navController = navController)
61 |
62 | Spacer(
63 | modifier = Modifier.height(80.dp).width(6.dp)
64 | .constrainAs(gapRef) {
65 | start.linkTo(parent.start)
66 | top.linkTo(headerRef.bottom)
67 | })
68 |
69 | Column(
70 | modifier = Modifier.fillMaxWidth()
71 | .constrainAs(itemsRef) {
72 | start.linkTo(parent.start)
73 | end.linkTo(parent.end)
74 | top.linkTo(gapRef.bottom)
75 | bottom.linkTo(buttonRef.top, margin = 24.dp)
76 | }
77 | ) {
78 | mockItems.forEach {
79 | ItemRow(data = it, isHighlighted = it.row == 2)
80 | }
81 | }
82 |
83 | BottomButton(modifier = Modifier.constrainAs(buttonRef) {
84 | bottom.linkTo(parent.bottom, margin = 24.dp)
85 | start.linkTo(parent.start)
86 | end.linkTo(parent.end)
87 | })
88 | }
89 |
90 | val cardState = transition(
91 | definition = detailsGraphTransitionDef, toState = "stop", initState = "start")
92 | GraphCard(
93 | modifier = Modifier
94 | .align(Alignment.TopCenter)
95 | .fillMaxWidth(0.85f)
96 | .offset(y = 200.dp)
97 | .height(180.dp)
98 | .drawLayer(
99 | cameraDistance = 40f,
100 | rotationX = cardState[detailsGraphRotationX]
101 | )
102 | )
103 | }
104 | }
105 |
106 | @Composable
107 | fun GraphCard(
108 | modifier: Modifier = Modifier
109 | ) {
110 | Surface(
111 | shape = RoundedCornerShape(16.dp),
112 | color = graphCardBg,
113 | elevation = 4.dp,
114 | modifier = modifier
115 | ) {
116 |
117 | }
118 | }
119 |
120 | @Composable
121 | @ExperimentalAnimationApi
122 | fun BottomButton(
123 | modifier: Modifier = Modifier
124 | ) {
125 | val buttonOffset = animatedFloat(initVal = 0f)
126 | val iconBgAlpha = animatedFloat(initVal = 0f)
127 | val iconScale = animatedFloat(initVal = 1f)
128 | var visibility by remember { mutableStateOf(false) }
129 |
130 |
131 |
132 | onActive{
133 | buttonOffset.animateTo(1f, tween(durationMillis = 1000, delayMillis = 200))
134 | iconScale.animateTo(0.1f, tween(durationMillis = 800, delayMillis = 400)) {_, _ ->
135 | iconScale.animateTo(1f, tween(durationMillis = 100))
136 | }
137 | }
138 |
139 | LaunchedEffect(subject = true) {
140 | delay(200L)
141 | visibility = !visibility
142 | }
143 |
144 | Box(
145 | modifier = modifier
146 | .clickable(onClick = {})
147 | .offset(y = lerp(120.dp, 0.dp, buttonOffset.value))
148 | .background(color = seeMoreBg, shape = RoundedCornerShape(32.dp))
149 | .fillMaxWidth(0.6f)
150 | .padding(start = 24.dp, end = 8.dp)
151 | .padding(vertical = 16.dp)
152 | ) {
153 | AnimatedVisibility(
154 | visible = visibility,
155 | enter = fadeIn() + expandHorizontally(
156 | expandFrom = Alignment.Start,
157 | animSpec = tween(durationMillis = 250, delayMillis = 50)
158 | ),
159 | modifier = Modifier.align(Alignment.CenterStart)
160 | ) {
161 | Text(
162 | text = "See more",
163 | color = Color.White,
164 | fontSize = 20.sp,
165 | fontWeight = FontWeight.Bold,
166 | modifier = Modifier.align(Alignment.CenterStart)
167 | )
168 | }
169 |
170 | Box(
171 | modifier = Modifier.size(32.dp)
172 | .align(Alignment.CenterEnd)
173 | .background(Color.White, shape = CircleShape)
174 | ) {
175 | Icon(
176 | Icons.Default.KeyboardArrowRight,
177 | tint = seeMoreBg,
178 | modifier = Modifier.align(Alignment.Center).drawLayer(scaleX = iconScale.value, scaleY = iconScale.value)
179 | )
180 | }
181 | }
182 | }
183 |
184 | @Composable
185 | fun Header(
186 | modifier: Modifier = Modifier,
187 | navController: NavController
188 | ) {
189 | val imgUrl = "https://i.pravatar.cc/200?img=30"
190 | val bgFloat = animatedFloat(initVal = 1f)
191 | val avatarFloat = animatedFloat(initVal = 0f)
192 | val counterBgAnim = animatedFloat(initVal = 0f)
193 | val counterOpacity = animatedFloat(initVal = 0f)
194 | val counterTextAnim = animatedFloat(initVal = 1f)
195 |
196 | onActive {
197 | bgFloat.animateTo(0f, tween(durationMillis = 800))
198 | avatarFloat.animateTo(1f, tween(durationMillis = 1000))
199 | counterBgAnim.animateTo(1f, tween(durationMillis = 500)) { _, _ ->
200 | counterOpacity.snapTo(1f)
201 | }
202 | counterTextAnim.animateTo(0f, tween(durationMillis = 400, delayMillis = 450)) { _, _ ->
203 | counterTextAnim.animateTo(1f)
204 | }
205 | }
206 |
207 | Box(
208 | modifier = modifier
209 | .height(300.dp)
210 | .drawLayer(translationY = with(DensityAmbient.current) { -320.dp.toPx() * bgFloat.value })
211 | .background(
212 | color = selectionHeaderBgColor,
213 | shape = RoundedCornerShape(bottomRight = 32.dp, bottomLeft = 32.dp))
214 | ) {
215 | IconButton(
216 | onClick = { navController.popBackStack() },
217 | modifier = Modifier.padding(top = 36.dp)
218 | ) {
219 | Icon(Icons.Default.ArrowBack, tint = Color.White)
220 | }
221 |
222 | Column(
223 | modifier = Modifier
224 | .fillMaxWidth()
225 | .padding(top = 36.dp)
226 | .padding(horizontal = 16.dp),
227 | ) {
228 | Column(
229 | modifier = Modifier.fillMaxWidth(),
230 | horizontalAlignment = Alignment.CenterHorizontally
231 | ) {
232 | Box(
233 | modifier = Modifier.size(84.dp)
234 | .offset(y = lerp(-32.dp, 0.dp, avatarFloat.value))
235 | .background(imageBgColor, shape = CircleShape)
236 | ) {
237 | CoilImage(
238 | data = imgUrl,
239 | modifier = Modifier.size(78.dp)
240 | .clip(CircleShape)
241 | .align(Alignment.Center)
242 | )
243 |
244 | Box(
245 | modifier = Modifier
246 | .offset(x = -2.dp, y = -2.dp)
247 | .size(24.dp)
248 | .drawLayer(alpha = counterOpacity.value)
249 | .background(color = Color.White, shape = CircleShape)
250 | .align(Alignment.BottomEnd)
251 |
252 | ) {
253 | Text(
254 | text = "23",
255 | color = headerCounterTextColor,
256 | modifier = Modifier.align(Alignment.Center)
257 | .drawLayer(scaleX = counterTextAnim.value, scaleY = counterTextAnim.value),
258 | fontWeight = FontWeight.ExtraBold,
259 | fontSize = 12.sp,
260 | )
261 | }
262 | }
263 |
264 | Spacer(modifier = Modifier.height(8.dp))
265 | Text(
266 | text = "Gabriella Estrada",
267 | color = selectionHeaderText,
268 | fontSize = 12.sp,
269 | fontWeight = FontWeight.Bold
270 | )
271 | }
272 | Spacer(modifier = Modifier.height(12.dp))
273 | Text(
274 | text = "Rent Surfing",
275 | color = selectionHeaderText,
276 | fontSize = 28.sp,
277 | fontWeight = FontWeight.Bold
278 | )
279 | }
280 | }
281 | }
282 |
283 | @Composable
284 | fun ItemRow(
285 | data: ItemRowData,
286 | isHighlighted: Boolean,
287 | modifier: Modifier = Modifier
288 | ) {
289 | Surface(
290 | color = if (isHighlighted) graphCardBg else surfaceColor,
291 | shape = if (isHighlighted) RoundedCornerShape(topRight = 56.dp) else RectangleShape,
292 | modifier = modifier.fillMaxWidth()
293 | ) {
294 | Row(
295 | modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp).padding(end = 24.dp),
296 | horizontalArrangement = Arrangement.spacedBy(16.dp)
297 | ) {
298 | Spacer(modifier = Modifier.size(8.dp))
299 | RowNumber(isHighlighted = isHighlighted, data.row)
300 | Column(horizontalAlignment = Alignment.Start) {
301 |
302 | Row(
303 | modifier = Modifier.fillMaxWidth(),
304 | horizontalArrangement = Arrangement.SpaceBetween
305 | ) {
306 | Text(text = data.country, color = textColorOne)
307 | Icon(
308 | Icons.Default.Star,
309 | tint = if (isHighlighted) selectedIconColor else unselectedColor,
310 | )
311 | }
312 | Spacer(modifier = Modifier.size(2.dp))
313 | Text(
314 | text = data.title,
315 | color = textColorTwo,
316 | fontSize = 18.sp,
317 | fontWeight = FontWeight.W500
318 | )
319 | Spacer(modifier = Modifier.size(2.dp))
320 | Row(
321 | modifier = Modifier.fillMaxWidth(),
322 | horizontalArrangement = Arrangement.SpaceBetween
323 | ) {
324 | Text(text = data.price, color = textColorOne)
325 | Text(
326 | text = "more",
327 | color = if (isHighlighted) selectedColor else unselectedColor,
328 | textDecoration = TextDecoration.Underline
329 | )
330 | }
331 | }
332 | }
333 | }
334 | }
335 |
336 | @Composable
337 | fun RowNumber(isHighlighted: Boolean, row: Int) {
338 |
339 | if (isHighlighted) {
340 | StyledRowNumber(width = 24.dp, height = 48.dp) {
341 | Text(
342 | text = "$row",
343 | modifier = Modifier.align(Alignment.Center),
344 | color = rowNumberTextColor
345 | )
346 | }
347 | } else {
348 | RegularRowNumber(row = row)
349 | }
350 | }
351 |
352 | @Composable
353 | fun RegularRowNumber(row: Int) {
354 | Box(
355 | modifier = Modifier
356 | .size(32.dp)
357 | .background(color = unselectedColor, shape = CircleShape)
358 | ) {
359 | Text(text = "$row", color = rowNumberTextColor, modifier = Modifier.align(Alignment.Center))
360 | }
361 | }
362 |
363 | @Composable
364 | fun StyledRowNumber(
365 | width: Dp,
366 | height: Dp,
367 | content: @Composable BoxScope.() -> Unit
368 | ) {
369 | Box(
370 | modifier = Modifier
371 | .width(width)
372 | .height(height)
373 | .drawIcon(bgColor = selectedColor)
374 | ) {
375 | content()
376 | }
377 | }
378 |
379 | fun Modifier.drawIcon(bgColor: Color) = this.drawBehind {
380 | val paint = Paint().apply {
381 | isAntiAlias = true
382 | color = bgColor
383 | }
384 |
385 | drawIntoCanvas { canvas ->
386 | val arcHeight = size.height / 4
387 |
388 | val rect = Rect(
389 | topLeft = Offset(0f, arcHeight),
390 | bottomRight = Offset(size.width, size.height - arcHeight)
391 | )
392 |
393 | canvas.drawRect(rect, paint)
394 |
395 | canvas.drawArc(
396 | left = 0f,
397 | top = 0f,
398 | right = size.width,
399 | bottom = arcHeight * 2,
400 | startAngle = 360f,
401 | sweepAngle = -180f,
402 | useCenter = false, paint = paint
403 | )
404 |
405 | canvas.drawArc(
406 | left = 0f,
407 | top = size.height - (arcHeight * 2),
408 | right = size.width,
409 | bottom = size.height,
410 | startAngle = 0f,
411 | sweepAngle = 180f,
412 | useCenter = false,
413 | paint = paint
414 | )
415 | }
416 | }
417 |
418 | data class ItemRowData(
419 | val row: Int,
420 | val country: String,
421 | val title: String,
422 | val price: String
423 | )
424 |
425 | val mockItems = listOf(
426 | ItemRowData(1, "Australia", "Rent Surfing on Sydney's", "from $61.00"),
427 | ItemRowData(2, "USA", "Rent Surfing on California", "from $72.00")
428 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/linegraph/GraphView.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.linegraph
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable fun GraphView(
6 |
7 | ) {
8 | /**
9 | * coordinates
10 | * y-axis (10, 12, 14)
11 | * x-axis (1,3,5,7,9)
12 | *
13 | * (10,1) (11, 2) (11, 3) (12.8, 4.7) (10, 5.2) (12, 6.9) (12,7.8)
14 | * (12.9, 9)
15 | */
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/linegraph/LineChartData.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.linegraph
2 |
3 | data class LineChartData(
4 | val points: List
5 | )
6 |
7 | data class Point(val xPos: Float, val yPos: Float)
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/ui/Color.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
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)
9 |
10 | val imageBgColor = Color(0xFFFFD353)
11 | val selectionHeaderBgColor = Color(0xFFFFBD00)
12 | val selectionHeaderText = Color(0xFFFEFFFE)
13 | val headerCounterTextColor = Color(0xFF5b5A61)
14 | val surfaceColor = Color(0xFFf8f9f8)
15 | val highlightedRowColor = Color(0xFFFDFEFD)
16 | val graphCardBg = Color(0xFFFEFFFE)
17 | val seeMoreBg = Color(0xFFFF0151)
18 |
19 | val unselectedColor = Color(0xFFcacbca)
20 | val rowNumberTextColor = Color(0xFFfefffe)
21 | val selectedColor = Color(0xFF2f2e38)
22 | val selectedIconColor = Color(0xFFffbd00)
23 |
24 | val textColorOne = Color(0xFFcacbca)
25 | val textColorTwo = Color(0xFF302f39)
26 |
27 | val weekBarBgColor = Color(0xFFf7f8f7)
28 | val dayBarLow = Color(0xFFffbd00)
29 | val dayBarHigh = Color(0xFF2f2e38)
30 | val lowDayTextColor = Color(0xFFcbcccb)
31 | val highDayTextColor = Color(0xFF35343d)
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/ui/ModifiersExt.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
2 |
3 | import androidx.compose.animation.animatedFloat
4 | import androidx.compose.animation.core.AnimatedFloat
5 | import androidx.compose.animation.core.tween
6 | import androidx.compose.runtime.onActive
7 | import androidx.compose.runtime.remember
8 | import androidx.compose.ui.*
9 | import androidx.compose.ui.geometry.toRect
10 | import androidx.compose.ui.graphics.Color
11 | import androidx.compose.ui.graphics.LinearGradientShader
12 | import androidx.compose.ui.graphics.Paint
13 | import androidx.compose.ui.graphics.PaintingStyle
14 | import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
15 |
16 | fun Modifier.shimmer() = composed {
17 | val progress = animatedFloat(initVal = 0f)
18 | onActive {
19 | progress.animateTo(1f, tween(durationMillis = 2000))
20 | onDispose {
21 | progress.stop()
22 | }
23 | }
24 | remember { ShimmerModifier(progress) }
25 | }
26 |
27 | private class ShimmerModifier(val t: AnimatedFloat): DrawModifier {
28 | private val shaderColors = listOf(
29 | Color(0xAAAAAA) ,
30 | Color(0xa2AAAAAA),
31 | Color(0xAAAAAA)
32 | )
33 |
34 | private val paint = Paint().apply {
35 | isAntiAlias = true
36 | style = PaintingStyle.Stroke
37 | color = Color(0xefefef)
38 | }
39 |
40 | override fun ContentDrawScope.draw() {
41 | paint.shader = LinearGradientShader(
42 | size.toRect().topLeft,
43 | size.toRect().bottomRight,
44 | shaderColors,
45 | listOf(0f, t.value, 1f)
46 | )
47 |
48 | drawIntoCanvas {
49 | it.drawRect(rect = size.toRect(), paint = paint)
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/ui/Shape.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
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/mobile/app/sporting/ui/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
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 SportingTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
32 | val colors = if (darkTheme) {
33 | DarkColorPalette
34 | } else {
35 | LightColorPalette
36 | }
37 |
38 | MaterialTheme(
39 | colors = colors,
40 | typography = typography,
41 | shapes = shapes,
42 | content = content
43 | )
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mobile/app/sporting/ui/Type.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
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/java/com/mobile/app/sporting/ui/transitions.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting.ui
2 |
3 | import androidx.compose.animation.ColorPropKey
4 | import androidx.compose.animation.DpPropKey
5 | import androidx.compose.animation.core.*
6 | import androidx.compose.ui.unit.dp
7 |
8 | val propKey = FloatPropKey()
9 | val textValueTransDef = transitionDefinition {
10 | state("start") {
11 | this[propKey] = 0.0f
12 | }
13 |
14 | state("end") {
15 | this[propKey] = 2.536f
16 | }
17 |
18 | transition("start" to "end") {
19 | propKey using keyframes {
20 | durationMillis = 400
21 | 0.0f at 0
22 | 1.5f at 150 with FastOutLinearInEasing
23 | 2.0f at 250 with FastOutSlowInEasing
24 | 2.536f at 400 with FastOutSlowInEasing
25 | }
26 | }
27 | }
28 |
29 | val topActivityOffset = DpPropKey()
30 | val topActivityTransDef = transitionDefinition {
31 | state("start") {
32 | this[topActivityOffset] = -32.dp
33 | }
34 |
35 | state("end") {
36 | this[topActivityOffset] = 0.dp
37 | }
38 |
39 | transition("start" to "end") {
40 | topActivityOffset using tween(
41 | durationMillis = 600,
42 | easing = LinearOutSlowInEasing
43 | )
44 | }
45 | }
46 |
47 | val ratingOffset = DpPropKey()
48 | val ratingTransDef = transitionDefinition {
49 | state("start") {
50 | this[ratingOffset] = -32.dp
51 | }
52 |
53 | state("end") {
54 | this[ratingOffset] = 0.dp
55 | }
56 |
57 | transition("start" to "end") {
58 | ratingOffset using tween(
59 | durationMillis = 800,
60 | easing = LinearOutSlowInEasing
61 | )
62 | }
63 | }
64 |
65 | val iconProp = FloatPropKey()
66 | val iconTransitionDefinition = transitionDefinition {
67 | state(1) {
68 | this[iconProp] = 1f
69 | }
70 |
71 | state(2) {
72 | this[iconProp] = 1f
73 | }
74 |
75 | transition(1 to 2) {
76 | iconProp using keyframes {
77 | durationMillis = 500
78 | 1f at 0 with LinearOutSlowInEasing
79 | 0.1f at 400 with LinearOutSlowInEasing
80 | 1f at 500 with FastOutSlowInEasing
81 | }
82 | }
83 | }
84 |
85 | val rotationX = FloatPropKey()
86 | val weekChartTransitionDef = transitionDefinition {
87 | state("start") {
88 | this[rotationX] = -180.0f
89 | }
90 |
91 | state("end") {
92 | this[rotationX] = 0f
93 | }
94 |
95 | transition("start" to "end") {
96 | rotationX using tween(
97 | durationMillis = 800,
98 | easing = LinearOutSlowInEasing
99 | )
100 | }
101 | }
102 |
103 | val detailsGraphRotationX = FloatPropKey()
104 | val detailsGraphTransitionDef = transitionDefinition {
105 | state("start") {
106 | this[detailsGraphRotationX] = -90f
107 | }
108 |
109 | state("stop") {
110 | this[detailsGraphRotationX] = 0f
111 | }
112 |
113 | transition("start" to "stop") {
114 | detailsGraphRotationX using tween(
115 | durationMillis = 200,
116 | delayMillis = 1000
117 | )
118 | }
119 | }
120 |
121 | val barLoadPropKey = FloatPropKey()
122 | val barLoadTransitionDef = transitionDefinition {
123 | state(1) {
124 | this[barLoadPropKey] = 1f
125 | }
126 |
127 | state(2) {
128 | this[barLoadPropKey] = 0f
129 | }
130 |
131 | transition(1 to 2) {
132 | barLoadPropKey using tween(
133 | durationMillis = 1500,
134 | easing = FastOutSlowInEasing//CubicBezierEasing(0.2f, 0.5f, 0.3f, 0.8f)
135 | )
136 | }
137 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pokeball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/drawable/pokeball.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/surfer_four.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/drawable/surfer_four.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/surfer_one.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/drawable/surfer_one.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/surfer_three.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/drawable/surfer_three.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/surfer_two.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/drawable/surfer_two.jpg
--------------------------------------------------------------------------------
/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.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/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 | Sporting
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/app/src/test/java/com/mobile/app/sporting/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.mobile.app.sporting
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 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext {
4 | compose_version = '1.0.0-alpha08'
5 | }
6 | ext.kotlin_version = "1.4.20"
7 | repositories {
8 | google()
9 | jcenter()
10 | }
11 | dependencies {
12 | classpath "com.android.tools.build:gradle:4.2.0-alpha15"
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 |
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | google()
23 | jcenter()
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
--------------------------------------------------------------------------------
/docs/dribbble_sport.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/docs/dribbble_sport.gif
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mayojava/Sporting/63c3b00317d021bf7511aae2bda023cfd7a11125/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Oct 31 18:53:26 CET 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = "Sporting"
2 | include ':app'
3 |
--------------------------------------------------------------------------------