-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[YDS-#228] Component - Toast 구현 #233
Merged
Merged
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
28718a8
MyScaffold, Toast 초기 후구현
Gael-Android 2939cd6
구현 완료
Gael-Android 8aad08b
리뷰 반영
Gael-Android 1cbb5da
리뷰 반영
Gael-Android c0a2e3b
리뷰 반영
Gael-Android 32a91bc
Merge branch 'develop' into feature/gael/toast
Gael-Android 20fd92c
디버그 용 함수 제거
Gael-Android f50cd8b
rememberToastHostState 생성
Gael-Android 2d3cc4d
ToastDuration Enum애 시간 정의
Gael-Android 95fe115
텍스트 가운데 정렬 로직 추가
Gael-Android 5087a57
rememberToastHost -> ToastHost.kt로 이동
Gael-Android 0988f5e
오타 수정
Gael-Android File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
package com.yourssu.design.system.compose.foundation | ||
package com.yourssu.design.system.compose.component.toast | ||
|
||
import android.util.Log | ||
import androidx.compose.animation.core.Animatable | ||
import androidx.compose.animation.core.AnimationSpec | ||
import androidx.compose.animation.core.tween | ||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
|
@@ -20,45 +20,48 @@ import androidx.compose.ui.graphics.graphicsLayer | |
import com.yourssu.design.system.compose.rule.Duration | ||
import com.yourssu.design.system.compose.rule.YdsInAndOutEasing | ||
|
||
data class ToastAnimationItem( | ||
data class ToastTransitionItem( | ||
val toastData: ToastData?, | ||
val opacityTransition: opacityTransition | ||
val opacityTransition: OpacityTransition | ||
) | ||
|
||
fun Any?.helpCode() = System.identityHashCode(this) % 1000 | ||
|
||
typealias opacityTransition = @Composable (toast: @Composable () -> Unit) -> Unit | ||
typealias OpacityTransition = @Composable (toast: @Composable () -> Unit) -> Unit | ||
|
||
/** | ||
* 토스트 애니메이션 FadeInFadeOut | ||
* | ||
* 구현과정 이해를 위해 주석을 남겨둘 예정입니다. | ||
* 작동 이해를 위해 주석을 남겨둘 예정입니다. | ||
* | ||
* @param newToastData 새로운 토스트 데이터 입력. 입력 없다면 null | ||
* @param modifier Modifier | ||
* @param toast 토스트 컴포저블 | ||
*/ | ||
@Composable | ||
fun FadeInFadeOutWithScale( | ||
fun FadeInFadeOut( | ||
newToastData: ToastData?, | ||
modifier: Modifier = Modifier, | ||
toast: @Composable (ToastData) -> Unit // Composable of Toast | ||
) { | ||
// 앞으로 나타나기로 예정된 토스트의 정보 | ||
var scheduledToastData by remember { mutableStateOf<ToastData?>(null) } | ||
val toastAnimations = remember { mutableListOf<ToastAnimationItem>() } | ||
// 현재 나타나고 있는 토스트의 정보와 Opacity Composable | ||
val toastTransitions = remember { mutableListOf<ToastTransitionItem>() } | ||
var scope by remember { mutableStateOf<RecomposeScope?>(null) } | ||
|
||
if (newToastData != scheduledToastData) { | ||
scheduledToastData = newToastData | ||
val toastDataList = toastAnimations.map { | ||
// 새로 발생한 토스트 != 앞으로 나타나기로 예정된 토스트의 정보 => 새 Toast 발생 | ||
scheduledToastData = newToastData // 앞으로 나타날 토스트에 새로운 토스트로 업데이트 | ||
val toastDataList = toastTransitions.map { | ||
it.toastData | ||
}.toMutableList() | ||
toastDataList.add(newToastData) | ||
toastAnimations.clear() | ||
}.toMutableList() // 현재 나타난 토스트의 정보로 초기회 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아주 사소한거지만 주석에 오타가 있네요! |
||
toastDataList.add(newToastData) // 새로 발생한 토스트 추가 | ||
toastTransitions.clear() // 현재 나타난 토스트 비우기 (새로운 토스트가 발생했으므로) | ||
toastDataList | ||
.filterNotNull() | ||
.mapTo(destination = toastAnimations) { appearedToastData -> | ||
ToastAnimationItem(appearedToastData) { toast -> | ||
.mapTo(destination = toastTransitions) { appearedToastData -> | ||
ToastTransitionItem(appearedToastData) { toast -> | ||
val isVisible = appearedToastData == newToastData | ||
val opacity = animatedOpacity( | ||
animation = tween( | ||
|
@@ -67,14 +70,15 @@ fun FadeInFadeOutWithScale( | |
durationMillis = Duration.Medium.millis | ||
), | ||
visible = isVisible, | ||
onAnimationFinish = { | ||
onAnimationFinish = { // 토스트가 사라질때 발동 | ||
if (appearedToastData != scheduledToastData) { | ||
toastAnimations.removeAll { it.toastData == appearedToastData } | ||
toastTransitions.removeAll { it.toastData == appearedToastData } | ||
// 발생한 토스트를 제거 | ||
scope?.invalidate() | ||
} | ||
} | ||
) | ||
Box( | ||
Box( // 투명도 그래픽 레이어를 만들어주는 Toast 상위 Composable | ||
Modifier | ||
.graphicsLayer( | ||
alpha = opacity.value | ||
|
@@ -88,7 +92,7 @@ fun FadeInFadeOutWithScale( | |
|
||
Box(modifier) { | ||
scope = currentRecomposeScope | ||
toastAnimations.forEach { (toastData, opacity) -> | ||
toastTransitions.forEach { (toastData, opacity) -> | ||
key(toastData) { | ||
opacity { | ||
toast(toastData!!) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
versionName=2.3.1 | ||
versionName=2.4.0 | ||
#자동 배포를 위해서 버전은 여기 한 군데에서 관리하면 된다 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
더이상 Layout으로 위치를 지정해줄 필요 없이 그냥 가운데 정렬만 하면 될 것 같은데 확인 부탁드립니다
(근데 토스트 명세에 텍스트가 한 줄이면 가운데 정렬, 여러 줄이면 왼쪽 정렬해야 하는데 이 부분을 처리하는 로직은 어디에 있는건가요?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이게 정말 이상한데,
// modifier = Modifier.align(
// Alignment.Center
// )
를 하기만 해도 텍스트가 한줄일때는 중앙정렬이 되고, 2줄이상 넘어갈때 좌측정렬이 자동으로 됩니다.
원래 방법으로는,
// onTextLayout = {
// lineCount = it.lineCount
// },
를 YdsText에 하고,
// if (lineCount == 1)
// Alignment.Center
// else
// Alignment.CenterStart
하면 정해진 로직대로 구현을 하는 방법입니다. 하지만 첫번째 방법이 이해할 수 없지만 작동하니
이건 어떻게 해야할지 잘 모르겠습니다. (이해도 안되고요...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그래도 일단 기획이 코드에 보여야하니까 아래의 방법으로 하겠습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 그러게요 희한하네요
텍스트 정렬하는 방법을 찾아보니 보통 modifier가 아니라 textAlign 속성을 지정해주는 방식으로 하더라구요 (https://kotlinworld.com/219)
Modifier.align이랑은 무슨 차이가 있을까요..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
내부 구현을 둘러보니까 일단 align 함수는 Box나 Column, Row 스코프 내에서만 사용할 수 있는 함수예요. 컨테이너 내부의 각 요소에 대해 어떻게 둘거냐를 지정하는거죠. 그래서 텍스트의 속성이라고 보긴 어려울 것 같아요.
그리고 Modifier.align(Center)를 하든 안 하든 텍스트 정렬은
TextAlign.Start
(좌측 정렬)가 기본이에요근데 왜 말씀하신 것처럼 한 줄일 때는 중앙 정렬이고 여러 줄일 때는 좌측 정렬인 것처럼 보일까요? 그림으로 직관적으로 보여드리자면
이렇게 그냥 텍스트가 짧으면 차지하는 영역이 작으니까 Box의 Center 속성 때문에 가운데에 있는 것처럼 보이는 거예요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위 링크의 textAlign 속성은 머티리얼 Text에만 있는거더라구요. 그래서 의도대로 하기 위해서는 YdsText를 수정해야 하는데 글로 쓰기는 길어지니까 이 PR 머지되고 나서 제가 직접 수정할게요. 지금은 그냥 이 상태로 두셔도 괜찮습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정말 그렇네요!! 저 이미지가 맞는거 같습니다.