Skip to content

Commit

Permalink
Add library core
Browse files Browse the repository at this point in the history
  • Loading branch information
abdullahalhakimi committed Aug 26, 2024
1 parent 2dded48 commit 97b2ee4
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 30 deletions.
8 changes: 6 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ plugins {
}

android {
namespace = "com.abdullahalhakimi.smoothmotion"
namespace = "com.abdullahalhakimi.smoothmotion.sample"
compileSdk = 34

defaultConfig {
applicationId = "com.abdullahalhakimi.smoothmotion"
applicationId = namespace
minSdk = 24
targetSdk = 34
versionCode = 1
Expand Down Expand Up @@ -66,4 +66,8 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

// import the library
implementation(project(":library"))

}
4 changes: 1 addition & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@
android:theme="@style/Theme.SmoothMotion"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name="com.abdullahalhakimi.smoothmotion.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.SmoothMotion">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Expand Down
86 changes: 63 additions & 23 deletions app/src/main/java/com/abdullahalhakimi/smoothmotion/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,84 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.abdullahalhakimi.smoothmotion.ui.theme.SmoothMotionTheme
import com.abdullahalhakimi.smoothmotion.animations.AnimatedButton
import com.abdullahalhakimi.smoothmotion.animations.ExpandingCard
import com.abdullahalhakimi.smoothmotion.animations.PulsatingLoadingIndicator
import com.abdullahalhakimi.smoothmotion.animations.RotatingIcon
import com.abdullahalhakimi.smoothmotion.animations.SlideTransition

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
SmoothMotionTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
ExampleMainActivityContent()
}
}
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
fun ExampleMainActivityContent() {
var isExpanded by remember { mutableStateOf(false) }
var showSlide by remember { mutableStateOf(true) }

Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// AnimatedButton Example
AnimatedButton(
onClick = { /* Do something */ },
modifier = Modifier.fillMaxWidth()
) {
Text("Animated Button")
}

// SlideTransition Example
SlideTransition(targetState = showSlide) {
Text("Slide In Content", modifier = Modifier.padding(16.dp))
}
Button(onClick = { showSlide = !showSlide }) {
Text(if (showSlide) "Hide Slide" else "Show Slide")
}

// PulsatingLoadingIndicator Example
PulsatingLoadingIndicator()

// ExpandingCard Example
ExpandingCard(
headerContent = { Text("Expanding Card Header") },
expandedContent = { Text("This is the expanded content of the card.") },
isExpanded = isExpanded,
onClick = { isExpanded = !isExpanded }
)

// RotatingIcon Example
RotatingIcon(
modifier = Modifier.size(60.dp),
icon = { Icon(Icons.Default.Refresh, contentDescription = "Rotating Icon") },
color = Color.Blue
)
}
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
SmoothMotionTheme {
Greeting("Android")
}
fun ExampleMainActivityPreview() {
ExampleMainActivityContent()
}
14 changes: 14 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
[versions]
agp = "8.5.0"
androidxJunit = "1.1.5"
animation = "1.6.8"
espressoCoreVersion = "3.5.1"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
Expand All @@ -10,9 +13,16 @@ activityCompose = "1.9.1"
composeBom = "2024.04.01"
appcompat = "1.7.0"
material = "1.12.0"
ui = "1.6.8"
uiTestJunit4 = "1.6.8"
uiTooling = "1.6.8"
uiToolingPreview = "1.6.8"

[libraries]
androidx-animation = { module = "androidx.compose.animation:animation", version.ref = "animation" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-espresso-core-v351 = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCoreVersion" }
androidx-junit-v115 = { module = "androidx.test.ext:junit", version.ref = "androidxJunit" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
Expand All @@ -28,6 +38,10 @@ androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
ui = { module = "androidx.compose.ui:ui", version.ref = "ui" }
ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "uiTestJunit4" }
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "uiTooling" }
ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "uiToolingPreview" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
Expand Down
File renamed without changes.
7 changes: 6 additions & 1 deletion SmoothMotion/build.gradle.kts → library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

android {
namespace = "com.abdullahalhakimi.smoothmotion"
namespace = "com.abdullahalhakimi.library"
compileSdk = 34

defaultConfig {
Expand Down Expand Up @@ -46,4 +46,9 @@ dependencies {
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation( libs.ui)
implementation( libs.androidx.animation)
implementation( libs.ui.tooling.preview)
androidTestImplementation( libs.androidx.espresso.core.v351)
debugImplementation( libs.ui.tooling)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.abdullahalhakimi.smoothmotion.animations

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp


@Composable
fun AnimatedButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
scaleDownValue: Float = 0.95f,
animationDuration: Int = 300,
cornerRadius: Int = 8,
padding: Int = 16,
content: @Composable () -> Unit
) {
var isPressed by remember { mutableStateOf(false) }
val scale by animateFloatAsState(
targetValue = if (isPressed) scaleDownValue else 1f,
animationSpec = tween(durationMillis = animationDuration)
)

Surface(
modifier = modifier
.graphicsLayer(scaleX = scale, scaleY = scale)
.clickable(
onClick = {
isPressed = true
onClick()
isPressed = false
}
),
shape = RoundedCornerShape(cornerRadius.dp),
color = MaterialTheme.colorScheme.primary
) {
Box(modifier = Modifier.padding(padding.dp)) {
content()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.abdullahalhakimi.smoothmotion.animations

import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun ExpandingCard(
headerContent: @Composable () -> Unit,
expandedContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
isExpanded: Boolean = false,
onClick: () -> Unit = {},
animationDuration: Int = 300,
cornerRadius: Int = 8,
padding: Int = 16
) {
Surface(
modifier = modifier
.fillMaxWidth()
.padding(padding.dp)
.clickable { onClick() }
.animateContentSize(tween(durationMillis = animationDuration)),
shape = RoundedCornerShape(cornerRadius.dp),
color = MaterialTheme.colorScheme.surface,
tonalElevation = 4.dp
) {
Column(modifier = Modifier.padding(padding.dp)) {
headerContent()
if (isExpanded) {
Spacer(modifier = Modifier.height(8.dp))
expandedContent()
}
}
}
}



//@Composable
//fun ExpandingCard(
// headerContent: @Composable () -> Unit,
// expandedContent: @Composable () -> Unit,
// modifier: Modifier = Modifier,
// animationDuration: Int = 300,
// cornerRadius: Int = 8,
// padding: Int = 16
//) {
// var expanded by remember { mutableStateOf(false) }
//
// Surface(
// modifier = modifier
// .fillMaxWidth()
// .padding(padding.dp)
// .clickable { expanded = !expanded }
// .animateContentSize(tween(durationMillis = animationDuration)),
// shape = RoundedCornerShape(cornerRadius.dp),
// color = MaterialTheme.colorScheme.surface,
// tonalElevation = 4.dp
// ) {
// Column(modifier = Modifier.padding(padding.dp)) {
// headerContent()
// if (expanded) {
// Spacer(modifier = Modifier.height(8.dp))
// expandedContent()
// }
// }
// }
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.abdullahalhakimi.smoothmotion.animations

import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun PulsatingLoadingIndicator(
modifier: Modifier = Modifier,
color: Color = Color.Blue,
size: Int = 50,
minScale: Float = 0.8f,
maxScale: Float = 1.2f,
pulsationDuration: Int = 1000,
easing: Easing = LinearEasing
) {
val infiniteTransition = rememberInfiniteTransition(label = "LoadingIndicator")
val scale by infiniteTransition.animateFloat(
initialValue = minScale,
targetValue = maxScale,
animationSpec = infiniteRepeatable(
animation = tween(pulsationDuration, easing = easing),
repeatMode = RepeatMode.Reverse
),
label = "LoadingIndicator",
)

Surface(
modifier = modifier
.size(size.dp)
.graphicsLayer(scaleX = scale, scaleY = scale),
color = color,
shape = CircleShape
) {}
}
Loading

0 comments on commit 97b2ee4

Please sign in to comment.