Skip to content

Commit 3acb150

Browse files
✨ Add support to load gifs in button animation
1 parent 3654118 commit 3acb150

9 files changed

Lines changed: 154 additions & 46 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
33

4+
<uses-permission android:name="android.permission.INTERNET" />
5+
46
<application
57
android:allowBackup="true"
68
android:icon="@mipmap/ic_launcher"

app/src/main/java/com/simform/ssjetpackcomposeprogressbutton/MainActivity.kt

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.simform.ssjetpackcomposeprogressbutton
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6-
import androidx.compose.foundation.BorderStroke
76
import androidx.compose.foundation.gestures.Orientation
87
import androidx.compose.foundation.gestures.ScrollableState
98
import androidx.compose.foundation.gestures.scrollable
@@ -28,15 +27,15 @@ import androidx.compose.material3.Button
2827
import androidx.compose.material3.ButtonDefaults
2928
import androidx.compose.material3.Text
3029
import androidx.compose.runtime.Composable
30+
import androidx.compose.runtime.getValue
3131
import androidx.compose.runtime.mutableStateOf
3232
import androidx.compose.runtime.remember
33-
import androidx.compose.runtime.getValue
3433
import androidx.compose.runtime.setValue
3534
import androidx.compose.ui.Alignment
3635
import androidx.compose.ui.Modifier
3736
import androidx.compose.ui.graphics.Color
38-
import androidx.compose.ui.graphics.SolidColor
3937
import androidx.compose.ui.graphics.vector.rememberVectorPainter
38+
import androidx.compose.ui.platform.LocalContext
4039
import androidx.compose.ui.res.colorResource
4140
import androidx.compose.ui.res.painterResource
4241
import androidx.compose.ui.res.stringResource
@@ -46,15 +45,16 @@ import androidx.compose.ui.text.font.FontWeight
4645
import androidx.compose.ui.tooling.preview.Preview
4746
import androidx.compose.ui.unit.dp
4847
import androidx.compose.ui.unit.sp
48+
import androidx.core.content.ContextCompat
4949
import com.simform.ssjetpackcomposeprogressbutton.utils.COMMON_BORDER_WIDTH
5050
import com.simform.ssjetpackcomposeprogressbutton.utils.COMMON_CORNER_RADIUS
5151
import com.simform.ssjetpackcomposeprogressbutton.utils.COMMON_HEIGHT
5252
import com.simform.ssjetpackcomposeprogressbutton.utils.COMMON_WIDTH
5353
import com.simform.ssjetpackcomposeprogressbutton.utils.FONT_SIZE
54-
import com.simform.ssjetpackcomposeprogressbutton.utils.TOP_BUTTON_HEIGHT
55-
import com.simform.ssjetpackcomposeprogressbutton.utils.TOP_BUTTON_RADIUS
5654
import com.simform.ssjetpackcomposeprogressbutton.utils.FORTY
5755
import com.simform.ssjetpackcomposeprogressbutton.utils.ONE_FLOAT
56+
import com.simform.ssjetpackcomposeprogressbutton.utils.TOP_BUTTON_HEIGHT
57+
import com.simform.ssjetpackcomposeprogressbutton.utils.TOP_BUTTON_RADIUS
5858
import com.simform.ssjetpackcomposeprogressbutton.utils.TWELVE
5959
import com.simform.ssjetpackcomposeprogressbutton.utils.TWO
6060
import com.simform.ssjetpackcomposeprogressbutton.utils.ZERO
@@ -63,6 +63,7 @@ import com.simform.ssjetpackcomposeprogressbuttonlibrary.SSButtonState
6363
import com.simform.ssjetpackcomposeprogressbuttonlibrary.SSButtonType
6464
import com.simform.ssjetpackcomposeprogressbuttonlibrary.SSCustomLoadingEffect
6565
import com.simform.ssjetpackcomposeprogressbuttonlibrary.SSJetPackComposeProgressButton
66+
import com.simform.ssjetpackcomposeprogressbuttonlibrary.gifPainter
6667
import com.simform.ssjetpackcomposeprogressbuttonlibrary.utils.ten
6768

6869
class MainActivity : ComponentActivity() {
@@ -72,6 +73,10 @@ class MainActivity : ComponentActivity() {
7273
SSLoadingButtonExample()
7374
}
7475
}
76+
77+
companion object {
78+
const val LOADING_GIF_URL = "https://media.tenor.com/CrhrU7ebGucAAAAi/unless-you-include-this.gif"
79+
}
7580
}
7681

7782
@Composable
@@ -89,6 +94,7 @@ fun SSLoadingButtonExample() {
8994
var customRotationButtonState: SSButtonState by remember { mutableStateOf(SSButtonState.IDLE) }
9095
var customZoomButtonState: SSButtonState by remember { mutableStateOf(SSButtonState.IDLE) }
9196
var customEffectButtonState: SSButtonState by remember { mutableStateOf(SSButtonState.IDLE) }
97+
var customGifButtonState: SSButtonState by remember { mutableStateOf(SSButtonState.IDLE) }
9298

9399
Column {
94100
Spacer(modifier = Modifier.size((TWELVE * TWO).dp))
@@ -113,6 +119,7 @@ fun SSLoadingButtonExample() {
113119
customRotationButtonState = SSButtonState.SUCCESS
114120
customZoomButtonState = SSButtonState.SUCCESS
115121
customEffectButtonState = SSButtonState.SUCCESS
122+
customGifButtonState = SSButtonState.SUCCESS
116123
},
117124
modifier = Modifier
118125
.padding(TWELVE.dp)
@@ -144,6 +151,7 @@ fun SSLoadingButtonExample() {
144151
customRotationButtonState = SSButtonState.FAILURE
145152
customEffectButtonState = SSButtonState.FAILURE
146153
customZoomButtonState = SSButtonState.FAILURE
154+
customGifButtonState = SSButtonState.FAILURE
147155
},
148156
modifier = Modifier
149157
.padding(TWELVE.dp)
@@ -182,10 +190,9 @@ fun SSLoadingButtonExample() {
182190
containerColor = Color.White,
183191
disabledContainerColor = Color.White
184192
),
185-
buttonBorderStroke = BorderStroke(
186-
COMMON_BORDER_WIDTH.dp,
187-
SolidColor(colorResource(id = R.color.pink))
188-
),
193+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
194+
animatedButtonBorderColor = colorResource(id = R.color.pink),
195+
buttonBorderColor = colorResource(id = R.color.pink),
189196
type = SSButtonType.CIRCLE,
190197
onClick = { roundedProgressState2 = SSButtonState.LOADING },
191198
buttonState = roundedProgressState2,
@@ -202,9 +209,9 @@ fun SSLoadingButtonExample() {
202209
containerColor = Color.White,
203210
disabledContainerColor = Color.White
204211
),
205-
buttonBorderStroke = BorderStroke(
206-
COMMON_BORDER_WIDTH.dp, SolidColor(colorResource(id = R.color.pink))
207-
),
212+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
213+
animatedButtonBorderColor = colorResource(id = R.color.pink),
214+
buttonBorderColor = colorResource(id = R.color.pink),
208215
type = SSButtonType.WHEEL,
209216
onClick = { wheelState = SSButtonState.LOADING },
210217
buttonState = wheelState,
@@ -220,10 +227,9 @@ fun SSLoadingButtonExample() {
220227
containerColor = Color.White,
221228
disabledContainerColor = Color.White
222229
),
223-
buttonBorderStroke = BorderStroke(
224-
COMMON_BORDER_WIDTH.dp,
225-
SolidColor(colorResource(id = R.color.pink))
226-
),
230+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
231+
animatedButtonBorderColor = colorResource(id = R.color.pink),
232+
buttonBorderColor = colorResource(id = R.color.pink),
227233
type = SSButtonType.ZOOM_IN_OUT_CIRCLE,
228234
onClick = { zoomInOutState = SSButtonState.LOADING },
229235
buttonState = zoomInOutState,
@@ -239,10 +245,9 @@ fun SSLoadingButtonExample() {
239245
containerColor = Color.White,
240246
disabledContainerColor = Color.White
241247
),
242-
buttonBorderStroke = BorderStroke(
243-
COMMON_BORDER_WIDTH.dp,
244-
SolidColor(colorResource(id = R.color.pink))
245-
),
248+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
249+
animatedButtonBorderColor = colorResource(id = R.color.pink),
250+
buttonBorderColor = colorResource(id = R.color.pink),
246251
type = SSButtonType.CLOCK,
247252
onClick = { clockState = SSButtonState.LOADING },
248253
buttonState = clockState,
@@ -258,10 +263,9 @@ fun SSLoadingButtonExample() {
258263
containerColor = Color.White,
259264
disabledContainerColor = Color.White
260265
),
261-
buttonBorderStroke = BorderStroke(
262-
COMMON_BORDER_WIDTH.dp,
263-
SolidColor(colorResource(id = R.color.pink))
264-
),
266+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
267+
animatedButtonBorderColor = colorResource(id = R.color.pink),
268+
buttonBorderColor = colorResource(id = R.color.pink),
265269
type = SSButtonType.SPIRAL,
266270
onClick = { spiralState = SSButtonState.LOADING },
267271
buttonState = spiralState,
@@ -390,10 +394,9 @@ fun SSLoadingButtonExample() {
390394
fontWeight = FontWeight.Bold,
391395
fontSize = FONT_SIZE.sp,
392396
leftImagePainter = painterResource(id = drawable.simform_logo),
393-
buttonBorderStroke = BorderStroke(
394-
COMMON_BORDER_WIDTH.dp,
395-
colorResource(id = R.color.pink)
396-
)
397+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
398+
animatedButtonBorderColor = colorResource(id = R.color.pink),
399+
buttonBorderColor = colorResource(id = R.color.pink)
397400
)
398401
SSJetPackComposeProgressButton(
399402
type = SSButtonType.CUSTOM,
@@ -420,10 +423,9 @@ fun SSLoadingButtonExample() {
420423
fontWeight = FontWeight.Bold,
421424
fontSize = FONT_SIZE.sp,
422425
leftImagePainter = painterResource(id = drawable.simform_logo),
423-
buttonBorderStroke = BorderStroke(
424-
COMMON_BORDER_WIDTH.dp,
425-
colorResource(id = R.color.pink)
426-
)
426+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
427+
animatedButtonBorderColor = colorResource(id = R.color.pink),
428+
buttonBorderColor = colorResource(id = R.color.pink)
427429
)
428430
SSJetPackComposeProgressButton(
429431
type = SSButtonType.CUSTOM,
@@ -452,13 +454,38 @@ fun SSLoadingButtonExample() {
452454
successIconColor = colorResource(id = R.color.dark_green),
453455
failureIconColor = colorResource(id = R.color.colorPrimaryDark),
454456
leftImagePainter = painterResource(id = drawable.simform_logo),
455-
buttonBorderStroke = BorderStroke(
456-
COMMON_BORDER_WIDTH.dp,
457-
colorResource(id = R.color.pink)
457+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
458+
animatedButtonBorderColor = colorResource(id = R.color.pink),
459+
buttonBorderColor = colorResource(id = R.color.pink)
460+
)
461+
SSJetPackComposeProgressButton(
462+
type = SSButtonType.CUSTOM,
463+
width = COMMON_WIDTH.dp,
464+
height = COMMON_HEIGHT.dp,
465+
customLoadingEffect = SSCustomLoadingEffect(gif = true),
466+
colors = ButtonDefaults.buttonColors(
467+
containerColor = Color.White,
468+
disabledContainerColor = Color.White
469+
),
470+
padding = PaddingValues(ten.dp),
471+
textModifier = Modifier.padding(ten.dp),
472+
fontWeight = FontWeight.Bold,
473+
fontSize = FONT_SIZE.sp,
474+
onClick = { customGifButtonState = SSButtonState.LOADING },
475+
assetColor = colorResource(id = R.color.pink),
476+
buttonState = customGifButtonState,
477+
text = stringResource(id = R.string.gif_loader),
478+
buttonBorderWidth = COMMON_BORDER_WIDTH.dp,
479+
animatedButtonBorderColor = Color.Transparent,
480+
buttonBorderColor = colorResource(id = R.color.pink),
481+
customLoadingIconPainter = gifPainter(
482+
data = MainActivity.LOADING_GIF_URL,
483+
drawable = ContextCompat.getDrawable(
484+
LocalContext.current,
485+
drawable.simform_logo
486+
)
458487
)
459488
)
460-
Spacer(modifier = Modifier.size(COMMON_WIDTH.dp))
461-
Spacer(modifier = Modifier.size(COMMON_WIDTH.dp))
462489
}
463490
}
464491
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
<string name="on_success">On Success</string>
77
<string name="on_failure">On Failure</string>
88
<string name="simform">SIMFORM</string>
9+
<string name="gif_loader">Gif Loader</string>
910

1011
</resources>

gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[versions]
22
activityCompose = "1.9.2"
33
appcompat = "1.7.0"
4+
coilCompose = "2.7.0"
45
espressoCore = "3.6.1"
56
junit = "4.13.2"
67
junitVersion = "1.2.1"
@@ -17,13 +18,15 @@ minSdk = "21"
1718
[libraries]
1819
activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }
1920
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
21+
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
2022
espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCore" }
2123
ext-junit = { module = "androidx.test.ext:junit", version.ref = "junitVersion" }
2224
junit = { module = "junit:junit", version.ref = "junit" }
2325
material = { module = "com.google.android.material:material", version.ref = "material" }
2426
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
2527
ui = { module = "androidx.compose.ui:ui", version.ref = "ui" }
2628
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "ui" }
29+
coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coilCompose" }
2730

2831
[plugins]
2932
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }

ssjetpackcomposeprogressbutton/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ android {
5656
dependencies {
5757
implementation(libs.ui)
5858
implementation(libs.material3)
59+
implementation(libs.coil.compose)
60+
implementation(libs.coil.gif)
5961
testImplementation(libs.junit)
6062
androidTestImplementation(libs.ext.junit)
6163
androidTestImplementation(libs.espresso.core)

ssjetpackcomposeprogressbutton/src/main/java/com/simform/ssjetpackcomposeprogressbuttonlibrary/CustomClass.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ data class SSCustomLoadingEffect (
44
var rotation: Boolean = false,
55
var zoomInOut: Boolean = false,
66
var colorChanger: Boolean = false,
7+
var gif: Boolean = false
78
)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.simform.ssjetpackcomposeprogressbuttonlibrary
2+
3+
import android.graphics.drawable.Drawable
4+
import android.os.Build
5+
import android.os.Build.VERSION.SDK_INT
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.remember
8+
import androidx.compose.ui.graphics.painter.Painter
9+
import androidx.compose.ui.platform.LocalContext
10+
import coil.ImageLoader
11+
import coil.compose.rememberAsyncImagePainter
12+
import coil.decode.GifDecoder
13+
import coil.decode.ImageDecoderDecoder
14+
import coil.request.ImageRequest
15+
import coil.size.Size
16+
17+
/**
18+
* @param data Set the data to load.
19+
* @param drawable Set the placeholder drawable to use when the request starts.
20+
**/
21+
@Composable
22+
fun gifPainter(data: Any?, drawable: Drawable?): Painter {
23+
val context = LocalContext.current
24+
val imageLoader = remember {
25+
ImageLoader.Builder(context)
26+
.components {
27+
if (SDK_INT >= Build.VERSION_CODES.P) {
28+
add(ImageDecoderDecoder.Factory())
29+
} else {
30+
add(GifDecoder.Factory())
31+
}
32+
}
33+
.build()
34+
}
35+
36+
return rememberAsyncImagePainter(
37+
model = ImageRequest.Builder(context)
38+
.data(data)
39+
.placeholder(drawable)
40+
.size(Size.ORIGINAL)
41+
.build(),
42+
imageLoader = imageLoader
43+
)
44+
}

ssjetpackcomposeprogressbutton/src/main/java/com/simform/ssjetpackcomposeprogressbuttonlibrary/PrintLoadingBar.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.simform.ssjetpackcomposeprogressbuttonlibrary
22

3+
import androidx.compose.foundation.Image
34
import androidx.compose.foundation.layout.size
5+
import androidx.compose.foundation.shape.CircleShape
46
import androidx.compose.material3.CircularProgressIndicator
57
import androidx.compose.material3.Icon
68
import androidx.compose.runtime.Composable
79
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.draw.clip
811
import androidx.compose.ui.draw.rotate
912
import androidx.compose.ui.graphics.Color
13+
import androidx.compose.ui.graphics.ColorFilter
1014
import androidx.compose.ui.graphics.graphicsLayer
1115
import androidx.compose.ui.graphics.painter.Painter
1216
import androidx.compose.ui.res.painterResource
@@ -125,14 +129,15 @@ fun PrintLoadingBar(
125129
},
126130
durationMillis = durationMillis
127131
)
128-
Icon(
132+
Image(
129133
painter = customLoadingIconPainter,
130-
contentDescription = null,
134+
contentDescription = "",
131135
modifier = Modifier
132136
.size(customSize)
133137
.graphicsLayer { alpha = progressAlpha }
134-
.rotate(customRotation),
135-
tint = customColor
138+
.rotate(customRotation)
139+
.clip(CircleShape),
140+
colorFilter = if (customLoadingEffect.gif) null else ColorFilter.tint(customColor)
136141
)
137142
}
138143

0 commit comments

Comments
 (0)