Skip to content

Commit 54ccbcc

Browse files
1. Added alpha animation
2. Added size change animation
1 parent 7fb244a commit 54ccbcc

File tree

6 files changed

+481
-315
lines changed

6 files changed

+481
-315
lines changed

core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagView.kt

Lines changed: 136 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package co.yml.coreui.core.ui.ytag
22

33
import android.R
4+
import android.annotation.SuppressLint
5+
import android.util.Log
6+
import androidx.compose.animation.AnimatedVisibility
7+
import androidx.compose.animation.core.*
8+
import androidx.compose.animation.fadeIn
9+
import androidx.compose.animation.fadeOut
410
import androidx.compose.foundation.background
511
import androidx.compose.foundation.border
612
import androidx.compose.foundation.clickable
@@ -11,8 +17,9 @@ import androidx.compose.material3.Icon
1117
import androidx.compose.material3.IconButton
1218
import androidx.compose.material3.Surface
1319
import androidx.compose.material3.Text
14-
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.*
1521
import androidx.compose.ui.Modifier
22+
import androidx.compose.ui.draw.alpha
1623
import androidx.compose.ui.graphics.Color
1724
import androidx.compose.ui.graphics.RectangleShape
1825
import androidx.compose.ui.platform.testTag
@@ -25,6 +32,7 @@ import androidx.compose.ui.unit.dp
2532
import androidx.compose.ui.unit.sp
2633
import androidx.constraintlayout.compose.ConstraintLayout
2734
import androidx.constraintlayout.compose.Dimension
35+
import co.yml.coreui.core.ui.ytag.model.TagViewData
2836
import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
2937

3038
/**
@@ -36,105 +44,151 @@ import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
3644
* @param enabled controls the enabled state of the TagView
3745
* @param tagViewModifiers collection of modifier elements that decorate or add behavior to TagView elements
3846
*/
47+
@SuppressLint("UnrememberedMutableState")
3948
@Composable
4049
fun TagView(
4150
text: String,
42-
leadingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
43-
trailingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
51+
leadingIcon: @Composable ((tagViewData: TagViewData) -> Unit)? = null,
52+
trailingIcon: @Composable ((tagViewData: TagViewData) -> Unit)? = null,
4453
enabled: Boolean = true,
4554
tagViewModifiers: TagViewModifiers = TagViewModifiers.Builder().build(),
46-
overFlowText: String = "",
47-
onClick: () -> Unit = {}
55+
overFlowText: String = ""
4856
) {
57+
val tagViewData = TagViewData(
58+
text = text,
59+
leadingIcon = leadingIcon,
60+
trailingIcon = trailingIcon,
61+
enabled = enabled,
62+
tagViewModifiers = tagViewModifiers,
63+
overFlowText = { overFlowText })
64+
65+
//used for visibility animation
66+
val state = remember {
67+
MutableTransitionState(false).apply {
68+
targetState = true
69+
}
70+
}
71+
72+
//used for alpha animation
73+
var tagVisible by remember {
74+
mutableStateOf(true)
75+
}
76+
77+
val tagAlpha: Float by animateFloatAsState(
78+
targetValue = if (tagVisible) 1f else 0f,
79+
animationSpec = tween(
80+
durationMillis = tagViewModifiers.alphaAnimation.durationMillis,
81+
easing = LinearEasing,
82+
),
83+
finishedListener = {
84+
//execute once remove animation is performed
85+
tagViewModifiers.onClick.invoke(tagViewData)
86+
}
87+
)
88+
4989
with(tagViewModifiers) {
50-
Surface(
51-
shadowElevation = shadowElevation,
52-
tonalElevation = tonalElevation,
53-
shape = shape,
54-
modifier = Modifier
55-
.testTag("tag_view")
56-
.width(width = width ?: Dp.Unspecified)
57-
.height(height = height)
90+
AnimatedVisibility(
91+
visibleState = state,
92+
enter = fadeIn(animationSpec = tween(alphaAnimation.durationMillis)),
93+
exit = fadeOut(animationSpec = tween(alphaAnimation.durationMillis))
5894
) {
59-
ConstraintLayout(
95+
Surface(
96+
shadowElevation = shadowElevation,
97+
tonalElevation = tonalElevation,
98+
shape = shape,
6099
modifier = Modifier
61-
.width(width = width ?: Dp.Unspecified)
62-
.height(height)
63-
.run {
64-
if (enableBorder) {
65-
border(
66-
width = borderWidth,
67-
color = borderColor,
68-
shape = shape
69-
)
70-
} else {
71-
background(color = backgroundColor, shape = shape)
100+
.testTag("tag_view")
101+
.width(width = width)
102+
.height(height = height)
103+
.alpha(tagAlpha)
104+
) {
105+
ConstraintLayout(
106+
modifier = Modifier
107+
108+
.width(width = width)
109+
.height(height)
110+
.run {
111+
if (enableBorder) {
112+
border(
113+
width = borderWidth,
114+
color = borderColor,
115+
shape = shape
116+
)
117+
} else {
118+
background(color = backgroundColor, shape = shape)
119+
}
72120
}
73-
}
74-
.clickable {
75-
if (enabled) {
76-
onClick.invoke()
77-
tagViewModifiers.onClick.invoke()
121+
.clickable {
122+
if (enabled) {
123+
if (tagViewModifiers.alphaAnimation.enabled){
124+
tagVisible = false
125+
state.targetState = false
126+
}else{
127+
tagViewModifiers.onClick.invoke(tagViewData)
128+
}
129+
}
78130
}
79-
}
80-
.defaultMinSize(minWidth = minWidth, minHeight = minHeight)
81-
.padding(containerPaddingValues)
82-
.background(
83-
color = backgroundColor,
84-
shape = shape
85-
)
86-
) {
87-
val (leading_icon, text_view, trailing_icon) = createRefs()
131+
.defaultMinSize(minWidth = minWidth, minHeight = minHeight)
132+
.padding(containerPaddingValues)
133+
.background(
134+
color = backgroundColor,
135+
shape = shape
136+
)
137+
88138

89-
Box(modifier = Modifier.constrainAs(leading_icon) {
90-
start.linkTo(parent.start)
91-
top.linkTo(parent.top)
92-
bottom.linkTo(parent.bottom)
93-
}
94139
) {
95-
leadingIcon?.invoke(enabled)
96-
}
140+
val (leading_icon, text_view, trailing_icon) = createRefs()
97141

98-
Text(
99-
text = overFlowText.ifEmpty { text },
100-
color = textColor,
101-
fontSize = fontSize,
102-
fontWeight = fontWeight,
103-
fontFamily = fontFamily,
104-
fontStyle = fontStyle,
105-
letterSpacing = letterSpacing,
106-
modifier = Modifier
107-
.constrainAs(text_view) {
108-
start.linkTo(leading_icon.end)
109-
end.linkTo(trailing_icon.start)
142+
Box(modifier = Modifier
143+
.constrainAs(leading_icon) {
144+
start.linkTo(parent.start)
110145
top.linkTo(parent.top)
111146
bottom.linkTo(parent.bottom)
112-
width = Dimension.fillToConstraints
113147
}
114-
.padding(
115-
textPadding
116-
)
117-
.semantics {
118-
this.contentDescription = semantics
119-
},
120-
style = style,
121-
textDecoration = textDecoration,
122-
textAlign = textAlign,
123-
lineHeight = lineHeight,
124-
overflow = overflow,
125-
softWrap = softWrap,
126-
maxLines = maxLines,
127-
onTextLayout = onTextLayout
128-
)
129-
Box(modifier = Modifier.constrainAs(trailing_icon) {
130-
end.linkTo(parent.end)
131-
top.linkTo(parent.top)
132-
bottom.linkTo(parent.bottom)
133-
}
134-
) {
135-
trailingIcon?.invoke(enabled)
136-
}
148+
) {
149+
leadingIcon?.invoke(tagViewData)
150+
}
137151

152+
Text(
153+
text = overFlowText.ifEmpty { text },
154+
color = textColor,
155+
fontSize = fontSize,
156+
fontWeight = fontWeight,
157+
fontFamily = fontFamily,
158+
fontStyle = fontStyle,
159+
letterSpacing = letterSpacing,
160+
modifier = Modifier
161+
.constrainAs(text_view) {
162+
start.linkTo(leading_icon.end)
163+
end.linkTo(trailing_icon.start)
164+
top.linkTo(parent.top)
165+
bottom.linkTo(parent.bottom)
166+
width = Dimension.fillToConstraints
167+
}
168+
.padding(
169+
textPadding
170+
)
171+
.semantics {
172+
this.contentDescription = semantics
173+
},
174+
style = style,
175+
textDecoration = textDecoration,
176+
textAlign = textAlign,
177+
lineHeight = lineHeight,
178+
overflow = overflow,
179+
softWrap = softWrap,
180+
maxLines = maxLines,
181+
onTextLayout = onTextLayout
182+
)
183+
Box(modifier = Modifier.constrainAs(trailing_icon) {
184+
end.linkTo(parent.end)
185+
top.linkTo(parent.top)
186+
bottom.linkTo(parent.bottom)
187+
}
188+
) {
189+
trailingIcon?.invoke(tagViewData)
190+
}
191+
}
138192
}
139193
}
140194
}

0 commit comments

Comments
 (0)