Skip to content

Commit 0fef3d9

Browse files
committed
feat: update toast design and allow custom toasts
1 parent 027c2c9 commit 0fef3d9

File tree

5 files changed

+120
-95
lines changed

5 files changed

+120
-95
lines changed
Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,80 @@
11
package com.aliernfrog.toptoast.component
22

3-
import androidx.compose.foundation.layout.*
4-
import androidx.compose.material3.*
3+
import androidx.compose.animation.animateContentSize
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.clickable
6+
import androidx.compose.foundation.interaction.MutableInteractionSource
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.layout.size
10+
import androidx.compose.material.ripple.rememberRipple
11+
import androidx.compose.material3.Icon
12+
import androidx.compose.material3.MaterialTheme
13+
import androidx.compose.material3.Text
14+
import androidx.compose.material3.surfaceColorAtElevation
515
import androidx.compose.runtime.Composable
16+
import androidx.compose.runtime.remember
617
import androidx.compose.ui.Alignment
718
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.draw.clip
20+
import androidx.compose.ui.draw.shadow
821
import androidx.compose.ui.graphics.Color
922
import androidx.compose.ui.graphics.painter.Painter
10-
import androidx.compose.ui.text.font.FontWeight
1123
import androidx.compose.ui.unit.dp
1224
import androidx.compose.ui.unit.sp
1325
import com.aliernfrog.toptoast.state.TopToastState
14-
import com.aliernfrog.toptoast.util.extensions.toastModifier
26+
import com.aliernfrog.toptoast.util.TopToastElevation
27+
import com.aliernfrog.toptoast.util.TopToastShape
1528

1629
/**
1730
* Top toast
1831
* @param state [TopToastState] of this toast
1932
*/
2033
@Composable
2134
fun TopToast(
35+
modifier: Modifier = Modifier,
2236
state: TopToastState? = null,
2337
text: String = state?.resolveText() ?: "",
2438
icon: Painter? = state?.resolveIcon(),
2539
iconTintColor: Color = state?.resolveIconTintColor() ?: MaterialTheme.colorScheme.primary,
2640
onClick: (() -> Unit)? = state?.onClick
2741
) {
28-
Column(
29-
modifier = Modifier
30-
.fillMaxWidth()
31-
.systemBarsPadding()
32-
.padding(top = 8.dp, bottom = 10.dp),
33-
horizontalAlignment = Alignment.CenterHorizontally
42+
Row(
43+
modifier = modifier
44+
.padding(TopToastElevation+1.4.dp) // avoid shadow getting cropped
45+
.shadow(TopToastElevation, TopToastShape)
46+
.clip(TopToastShape)
47+
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
48+
.animateContentSize()
49+
.run { onClick?.let {
50+
clickable(
51+
interactionSource = remember { MutableInteractionSource() },
52+
indication = rememberRipple(color = MaterialTheme.colorScheme.onBackground),
53+
onClick = it
54+
)
55+
} ?: this }
56+
.padding(
57+
horizontal = 16.dp
58+
),
59+
verticalAlignment = Alignment.CenterVertically
3460
) {
35-
Row(
61+
icon?.let { Icon(
62+
painter = icon,
63+
contentDescription = null,
64+
tint = iconTintColor,
3665
modifier = Modifier
37-
.padding(horizontal = 24.dp)
38-
.toastModifier(onClick)
39-
) {
40-
if (icon != null) Icon(
41-
painter = icon,
42-
contentDescription = null,
43-
tint = iconTintColor,
44-
modifier = Modifier.padding(end = 8.dp).size(25.dp).padding(1.dp).align(Alignment.CenterVertically)
45-
)
46-
Text(
47-
text = text,
48-
lineHeight = 20.sp,
49-
fontSize = 16.sp,
50-
fontWeight = FontWeight.Bold,
51-
color = MaterialTheme.colorScheme.onBackground,
52-
modifier = Modifier.align(Alignment.CenterVertically)
53-
)
54-
}
66+
.padding(end = 8.dp)
67+
.size(26.dp)
68+
) }
69+
Text(
70+
text = text,
71+
style = MaterialTheme.typography.labelLarge.copy(
72+
lineHeight = 18.sp
73+
),
74+
color = MaterialTheme.colorScheme.onBackground,
75+
modifier = Modifier
76+
.align(Alignment.CenterVertically)
77+
.padding(vertical = 12.dp)
78+
)
5579
}
5680
}
Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package com.aliernfrog.toptoast.component
22

3-
import androidx.compose.animation.*
3+
import androidx.compose.animation.AnimatedVisibility
44
import androidx.compose.animation.core.tween
5+
import androidx.compose.animation.fadeIn
6+
import androidx.compose.animation.fadeOut
7+
import androidx.compose.animation.slideInVertically
8+
import androidx.compose.animation.slideOutVertically
9+
import androidx.compose.foundation.layout.Box
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.systemBarsPadding
513
import androidx.compose.material3.ExperimentalMaterial3Api
614
import androidx.compose.material3.SwipeToDismissBox
715
import androidx.compose.material3.SwipeToDismissBoxValue
816
import androidx.compose.material3.rememberSwipeToDismissBoxState
917
import androidx.compose.runtime.Composable
18+
import androidx.compose.ui.Alignment
1019
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.unit.dp
1121
import com.aliernfrog.toptoast.state.TopToastState
1222

1323
/**
@@ -19,7 +29,10 @@ import com.aliernfrog.toptoast.state.TopToastState
1929
@Composable
2030
fun TopToastHost(
2131
state: TopToastState,
22-
modifier: Modifier = Modifier
32+
modifier: Modifier = Modifier,
33+
toast: @Composable (TopToastState) -> Unit = {
34+
TopToast(state = it)
35+
}
2336
) {
2437
AnimatedVisibility(
2538
visible = state.isShowing,
@@ -37,20 +50,28 @@ fun TopToastHost(
3750
animationSpec = tween(durationMillis = 150)
3851
)
3952
) {
40-
if (state.allowSwipeToDismiss) SwipeToDismissBox(
41-
state = rememberSwipeToDismissBoxState(
42-
confirmValueChange = {
43-
val dismissed =
44-
it == SwipeToDismissBoxValue.StartToEnd || it == SwipeToDismissBoxValue.EndToStart
45-
if (dismissed) state.dismissToast()
46-
true
53+
Box(
54+
modifier = Modifier
55+
.systemBarsPadding()
56+
.fillMaxWidth()
57+
.padding(top = 8.dp, start = 24.dp, end = 24.dp),
58+
contentAlignment = Alignment.Center
59+
) {
60+
if (state.allowSwipeToDismiss) SwipeToDismissBox(
61+
state = rememberSwipeToDismissBoxState(
62+
confirmValueChange = {
63+
val dismissed =
64+
it == SwipeToDismissBoxValue.StartToEnd || it == SwipeToDismissBoxValue.EndToStart
65+
if (dismissed) state.dismissToast()
66+
true
67+
}
68+
),
69+
backgroundContent = {},
70+
content = {
71+
toast(state)
4772
}
48-
),
49-
backgroundContent = {},
50-
content = {
51-
TopToast(state)
52-
}
53-
)
54-
else TopToast(state)
73+
)
74+
else toast(state)
75+
}
5576
}
5677
}

library/src/main/java/com/aliernfrog/toptoast/state/TopToastState.kt

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,32 @@ package com.aliernfrog.toptoast.state
33
import android.view.Gravity
44
import android.view.View
55
import android.widget.Toast
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
69
import androidx.compose.runtime.Composable
710
import androidx.compose.runtime.getValue
811
import androidx.compose.runtime.mutableStateOf
912
import androidx.compose.runtime.setValue
13+
import androidx.compose.ui.Alignment
14+
import androidx.compose.ui.Modifier
1015
import androidx.compose.ui.graphics.Color
1116
import androidx.compose.ui.graphics.painter.Painter
1217
import androidx.compose.ui.graphics.vector.ImageVector
1318
import androidx.compose.ui.graphics.vector.rememberVectorPainter
1419
import androidx.compose.ui.platform.ComposeView
1520
import androidx.compose.ui.res.painterResource
1621
import androidx.compose.ui.res.stringResource
22+
import androidx.compose.ui.unit.dp
1723
import androidx.lifecycle.findViewTreeLifecycleOwner
1824
import androidx.lifecycle.setViewTreeLifecycleOwner
1925
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
2026
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
2127
import com.aliernfrog.toptoast.component.TopToast
2228
import com.aliernfrog.toptoast.enum.TopToastColor
2329
import com.aliernfrog.toptoast.enum.TopToastType
24-
import java.util.*
30+
import java.util.Timer
31+
import java.util.TimerTask
2532
import kotlin.concurrent.schedule
2633

2734
/**
@@ -36,7 +43,14 @@ class TopToastState(
3643
private var appTheme: (@Composable (content: @Composable () -> Unit) -> Unit)?,
3744
@Deprecated("This is no longer needed as showAndroidToast is now a separate method. Will be removed in next releases.")
3845
private val defaultType: TopToastType = TopToastType.INTERACTIVE,
39-
private val allowSwipingByDefault: Boolean = true
46+
private val allowSwipingByDefault: Boolean = true,
47+
private val defaultAndroidToast: @Composable (text: String, icon: Painter?, iconTintColor: Color) -> Unit = { title, icon, iconTintColor ->
48+
TopToast(
49+
text = title,
50+
icon = icon,
51+
iconTintColor = iconTintColor
52+
)
53+
}
4054
) {
4155
/**
4256
* Whether any interactive toast is being shown
@@ -248,11 +262,18 @@ class TopToastState(
248262
topToastView.setContent {
249263
@Composable
250264
fun Toast() {
251-
TopToast(
252-
text = resolveText(text),
253-
icon = resolveIcon(icon),
254-
iconTintColor = resolveIconTintColor(iconTintColor)
255-
)
265+
Box(
266+
modifier = Modifier
267+
.fillMaxWidth()
268+
.padding(top = 8.dp, start = 24.dp, end = 24.dp), // avoid shadow getting cropped
269+
contentAlignment = Alignment.Center
270+
) {
271+
defaultAndroidToast(
272+
resolveText(text),
273+
resolveIcon(icon),
274+
resolveIconTintColor(iconTintColor)
275+
)
276+
}
256277
}
257278

258279
appTheme?.invoke {

library/src/main/java/com/aliernfrog/toptoast/util/Constant.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ package com.aliernfrog.toptoast.util
33
import androidx.compose.foundation.shape.RoundedCornerShape
44
import androidx.compose.ui.unit.dp
55

6-
val toastShape = RoundedCornerShape(30.dp)
6+
val TopToastShape = RoundedCornerShape(24.dp)
7+
val TopToastElevation = 3.dp

library/src/main/java/com/aliernfrog/toptoast/util/extensions/Modifier.kt

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)