diff --git a/app/src/main/res/raw/mock.json b/app/src/main/res/raw/mock.json index 0a82cee..e30a375 100644 --- a/app/src/main/res/raw/mock.json +++ b/app/src/main/res/raw/mock.json @@ -7527,5 +7527,157 @@ "text": "Text 2" } } + }, + "scrollDirectionMock": { + "data": { + "list": { + "viewType": "LazyColumn", + "scrollDirection": { + "up": { + "actions": [ + { + "type": "UpdateDataAction", + "viewDataList": [ + { + "layoutId": "item_text", + "data": { + "viewType": "Text", + "text": "Scrolling Up" + } + } + ] + } + + ] + }, + "down": { + "actions": [ + { + "type": "UpdateDataAction", + "viewDataList": [ + { + "layoutId": "item_text", + "data": { + "viewType": "Text", + "text": "Scrolling Down" + } + } + ] + } + ] + } + } + }, + "item_text": { + "viewType": "Text", + "text": "List Item" + } + }, + "view": [ + { + "property": { + "viewType": "LazyColumn", + "width": "MATCH_PARENT", + "layoutId": "list", + "height": "WRAP_CONTENT", + "horizontalAlignment": "Start", + "verticalScroll": { + "enabled": true + } + }, + "childrenViews": [ + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + }, + { + "property": { + "viewType": "Text", + "layoutId": "item_text", + "width": "MATCH_PARENT", + "height": "100", + "isStateFul": true + } + } + ] + } + ] } } \ No newline at end of file diff --git a/navi-uitron/src/main/java/com/navi/uitron/helpers/ScrollEventHandler.kt b/navi-uitron/src/main/java/com/navi/uitron/helpers/ScrollEventHandler.kt index a0c767a..edc200b 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/helpers/ScrollEventHandler.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/helpers/ScrollEventHandler.kt @@ -10,10 +10,14 @@ package com.navi.uitron.helpers import androidx.compose.foundation.lazy.LazyListState import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import com.navi.uitron.model.data.ScrollAction +import com.navi.uitron.model.data.ScrollDirection import com.navi.uitron.viewmodel.UiTronViewModel import dpToPx +import androidx.compose.runtime.setValue +import androidx.compose.runtime.getValue class ScrollEventHandler(private val viewModel: UiTronViewModel) { @@ -75,4 +79,32 @@ class ScrollEventHandler(private val viewModel: UiTronViewModel) { viewModel.handleActions(scrollAction?.down) } } + + @Composable + fun ScrollDirectionChangeListener(listState: LazyListState, scrollDirection: ScrollDirection) { + if (listState.isScrollingUp()) { + viewModel.handleActions(scrollDirection.up) + } else { + viewModel.handleActions(scrollDirection.down) + } + } + + @Composable + private fun LazyListState.isScrollingUp(): Boolean { + var previousIndex by remember(this) { mutableStateOf(firstVisibleItemIndex) } + var previousScrollOffset by remember(this) { mutableStateOf(firstVisibleItemScrollOffset) } + return remember(this) { + derivedStateOf { + if (previousIndex != firstVisibleItemIndex) { + previousIndex > firstVisibleItemIndex + } else { + previousScrollOffset >= firstVisibleItemScrollOffset + }.also { + previousIndex = firstVisibleItemIndex + previousScrollOffset = firstVisibleItemScrollOffset + } + } + }.value + } + } diff --git a/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyColumnData.kt b/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyColumnData.kt index 2f25675..9842900 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyColumnData.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyColumnData.kt @@ -12,8 +12,8 @@ import com.google.gson.annotations.SerializedName class LazyColumnData( @SerializedName("scrollData") val scrollData: Map? = null, - @SerializedName("childrenDataList") - var childrenDataList: List? = null + @SerializedName("scrollDirection") + val scrollDirection: ScrollDirection? = null ) : UiTronData() data class ScrollAction( @@ -24,3 +24,10 @@ data class ScrollAction( @SerializedName("down") val down: UiTronActionData? = null ) + +data class ScrollDirection( + @SerializedName("up") + val up: UiTronActionData? = null, + @SerializedName("down") + val down: UiTronActionData? = null +) \ No newline at end of file diff --git a/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyRowData.kt b/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyRowData.kt index 0f88d35..51ee579 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyRowData.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/model/data/LazyRowData.kt @@ -12,6 +12,6 @@ import com.google.gson.annotations.SerializedName class LazyRowData( @SerializedName("scrollData") val scrollData: Map? = null, - @SerializedName("childrenDataList") - var childrenDataList: List? = null + @SerializedName("scrollDirection") + val scrollDirection: ScrollDirection? = null ) : UiTronData() diff --git a/navi-uitron/src/main/java/com/navi/uitron/render/AnimationRenderer.kt b/navi-uitron/src/main/java/com/navi/uitron/render/AnimationRenderer.kt index ab7db46..7c17c38 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/render/AnimationRenderer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/render/AnimationRenderer.kt @@ -9,8 +9,10 @@ package com.navi.uitron.render import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.* +import androidx.compose.animation.expandIn import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkOut import androidx.compose.foundation.layout.Box import androidx.compose.runtime.* import androidx.compose.ui.Modifier @@ -122,12 +124,18 @@ class AnimationRenderer( .scale(scaleX = scaleXAnimation, scaleY = scaleYAnimation)) { AnimatedVisibility( visible = property.visible.orTrue(), - enter = fadeIn( - animationSpec = tween(property.fadeIn?.durationInMillis.orZero()) - ), - exit = fadeOut( - animationSpec = tween(property.fadeOut?.durationInMillis.orZero()) - ), + enter = property.fadeIn?.let { + fadeIn(animationSpec = tween(property.fadeIn?.durationInMillis.orZero())) + } ?: run { + fadeIn() + expandIn() + }, + exit = property.fadeOut?.let { + fadeOut( + animationSpec = tween(property.fadeOut?.durationInMillis.orZero()) + ) + } ?: run { + shrinkOut() + fadeOut() + }, ) { uiTronRenderer.Render(composeViews = childrenComposeViews) } diff --git a/navi-uitron/src/main/java/com/navi/uitron/render/LazyColumnRenderer.kt b/navi-uitron/src/main/java/com/navi/uitron/render/LazyColumnRenderer.kt index e101410..9c0fec1 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/render/LazyColumnRenderer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/render/LazyColumnRenderer.kt @@ -100,10 +100,10 @@ class LazyColumnRenderer( } } lazyColumnData?.scrollData?.let { - scrollEventHandler.HandleListScroll( - listState = lazyListState, - scrollData = it - ) + scrollEventHandler.HandleListScroll(listState = lazyListState, scrollData = it) + } + lazyColumnData?.scrollDirection?.let { + scrollEventHandler.ScrollDirectionChangeListener(lazyListState, it) } } } diff --git a/navi-uitron/src/main/java/com/navi/uitron/render/LazyRowRenderer.kt b/navi-uitron/src/main/java/com/navi/uitron/render/LazyRowRenderer.kt index 279b096..48aa4d4 100644 --- a/navi-uitron/src/main/java/com/navi/uitron/render/LazyRowRenderer.kt +++ b/navi-uitron/src/main/java/com/navi/uitron/render/LazyRowRenderer.kt @@ -107,6 +107,9 @@ class LazyRowRenderer( scrollData = it ) } + lazyRowData?.scrollDirection?.let { + scrollEventHandler.ScrollDirectionChangeListener(lazyListState, it) + } } }