Skip to content

Commit

Permalink
[FEAT]#111: BottomTab 전환 속도를 조절해요
Browse files Browse the repository at this point in the history
  • Loading branch information
flash159483 committed Aug 19, 2024
1 parent 680fc2a commit b76d197
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
8 changes: 5 additions & 3 deletions app/src/main/kotlin/com/bff/wespot/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand Down Expand Up @@ -67,6 +67,7 @@ import com.bff.wespot.navigation.Navigator
import com.bff.wespot.ui.TopToast
import com.bff.wespot.state.MainAction
import com.bff.wespot.viewmodel.MainViewModel
import com.bff.wespot.util.clickableSingle
import com.ramcosta.composedestinations.dynamic.within
import com.ramcosta.composedestinations.navigation.navigate
import com.ramcosta.composedestinations.spec.NavGraphSpec
Expand Down Expand Up @@ -311,7 +312,7 @@ private fun NavController.checkCurrentScreen(position: NavigationBarPosition): S
}

@Composable
private fun TabItem(
private fun RowScope.TabItem(
icon: Painter,
emptyIcon: Painter,
title: String,
Expand All @@ -322,7 +323,8 @@ private fun TabItem(
Box(
modifier = Modifier
.size(80.dp)
.clickable { onClick.invoke() },
.weight(1f)
.clickableSingle { onClick.invoke() },
contentAlignment = Alignment.Center,
) {
Column(
Expand Down
33 changes: 33 additions & 0 deletions core/ui/src/main/kotlin/com/bff/wespot/util/ModifierUtil.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package com.bff.wespot.util

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.pager.PagerState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.util.lerp
import kotlin.math.absoluteValue

Expand All @@ -23,3 +30,29 @@ fun Modifier.carouselTransition(pagerState: PagerState, page: Int) =
scaleY = transformation
scaleX = transformation
}

fun Modifier.clickableSingle(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit
) = composed(
inspectorInfo = debugInspectorInfo {
name = "clickable"
properties["enabled"] = enabled
properties["onClickLabel"] = onClickLabel
properties["role"] = role
properties["onClick"] = onClick
}
) {
multipleEventsCutter { manager ->
Modifier.clickable(
enabled = enabled,
onClickLabel = onClickLabel,
onClick = { manager.processEvent { onClick() } },
role = role,
indication = LocalIndication.current,
interactionSource = remember { MutableInteractionSource() }
)
}
}
45 changes: 45 additions & 0 deletions core/ui/src/main/kotlin/com/bff/wespot/util/MultiClickCutter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.bff.wespot.util

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.debounce

interface MultipleEventsCutterManager {
fun processEvent(event: () -> Unit)
}

@OptIn(FlowPreview::class)
@Composable
fun <T>multipleEventsCutter(
content: @Composable (MultipleEventsCutterManager) -> T
) : T {
val debounceState = remember {
MutableSharedFlow<() -> Unit>(
replay = 0,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
}

val result = content(
object : MultipleEventsCutterManager {
override fun processEvent(event: () -> Unit) {
debounceState.tryEmit(event)
}
}
)

LaunchedEffect(true) {
debounceState
.debounce(300L)
.collect { onClick ->
onClick.invoke()
}
}

return result
}

0 comments on commit b76d197

Please sign in to comment.