Skip to content

Commit e585ba4

Browse files
committed
feat(android): implement drag events
1 parent 2f0cec5 commit e585ba4

File tree

3 files changed

+83
-11
lines changed

3 files changed

+83
-11
lines changed

android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt

+53-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.lodev09.truesheet.core.RootSheetView
1515
import com.lodev09.truesheet.core.Utils
1616
import com.lodev09.truesheet.events.ContainerSizeChangeEvent
1717
import com.lodev09.truesheet.events.DismissEvent
18+
import com.lodev09.truesheet.events.DragEvent
1819
import com.lodev09.truesheet.events.MountEvent
1920
import com.lodev09.truesheet.events.PresentEvent
2021
import com.lodev09.truesheet.events.SizeChangeEvent
@@ -33,6 +34,11 @@ class TrueSheetView(context: Context) :
3334
var initialIndex: Int = -1
3435
var initialIndexAnimated: Boolean = true
3536

37+
/**
38+
* Determines if the sheet is being dragged by the user.
39+
*/
40+
private var isDragging = false
41+
3642
/**
3743
* Current activeIndex.
3844
*/
@@ -113,6 +119,16 @@ class TrueSheetView(context: Context) :
113119
behavior.addBottomSheetCallback(
114120
object : BottomSheetBehavior.BottomSheetCallback() {
115121
override fun onSlide(sheetView: View, slideOffset: Float) {
122+
// We only dispatch event if user is actually dragging to be more consistent with IOS
123+
// i.e. We ignore SETTLING state
124+
if (isDragging && sheetDialog.behavior.state == BottomSheetBehavior.STATE_DRAGGING) {
125+
val height = maxScreenHeight - sheetView.top
126+
val sizeInfo = SizeInfo(currentSizeIndex, Utils.toDIP(height.toFloat()))
127+
128+
// Dispatch drag change event
129+
eventDispatcher?.dispatchEvent(DragEvent(surfaceId, id, DRAG_STATE_CHANGED, sizeInfo))
130+
}
131+
116132
footerView?.let {
117133
val y = (maxScreenHeight - sheetView.top - footerHeight).toFloat()
118134
if (slideOffset >= 0) {
@@ -125,23 +141,45 @@ class TrueSheetView(context: Context) :
125141
}
126142
}
127143

128-
override fun onStateChanged(view: View, newState: Int) {
144+
override fun onStateChanged(sheetView: View, newState: Int) {
129145
if (!isShowing) return
130146

131-
val sizeInfo = getSizeInfoForState(newState)
132-
if (sizeInfo == null || sizeInfo.index == currentSizeIndex) return
147+
// When changed to dragging, we know that the drag has started
148+
if (newState == BottomSheetBehavior.STATE_DRAGGING) {
149+
val height = maxScreenHeight - sheetView.top
150+
val sizeInfo = SizeInfo(currentSizeIndex, Utils.toDIP(height.toFloat()))
151+
152+
// Dispatch drag started event
153+
eventDispatcher?.dispatchEvent(DragEvent(surfaceId, id, DRAG_STATE_BEGAN, sizeInfo))
133154

134-
// Invoke promise when sheet resized programmatically
135-
presentPromise?.let { promise ->
136-
promise()
137-
presentPromise = null
155+
// Flag sheet is being dragged
156+
isDragging = true
157+
return
138158
}
139159

140-
currentSizeIndex = sizeInfo.index
141-
setupDimmedBackground(sizeInfo.index)
160+
val sizeInfo = getSizeInfoForState(newState)
161+
sizeInfo?.let {
162+
// If from drag, dispatch ended event
163+
// We assume that if sizeInfo is available, it's one of the valid state
164+
if (isDragging) {
165+
eventDispatcher?.dispatchEvent(DragEvent(surfaceId, id, DRAG_STATE_ENDED, it))
166+
isDragging = false
167+
}
168+
169+
if (it.index != currentSizeIndex) {
170+
// Invoke promise when sheet resized programmatically
171+
presentPromise?.let { promise ->
172+
promise()
173+
presentPromise = null
174+
}
175+
176+
currentSizeIndex = it.index
177+
setupDimmedBackground(it.index)
142178

143-
// Dispatch onSizeChange event
144-
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
179+
// Dispatch onSizeChange event
180+
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, it))
181+
}
182+
}
145183
}
146184
}
147185
)
@@ -339,6 +377,10 @@ class TrueSheetView(context: Context) :
339377
}
340378

341379
companion object {
380+
const val DRAG_STATE_BEGAN = "began"
381+
const val DRAG_STATE_CHANGED = "changed"
382+
const val DRAG_STATE_ENDED = "ended"
383+
342384
const val TAG = "TrueSheetView"
343385
}
344386
}

android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.facebook.react.uimanager.annotations.ReactProp
1313
import com.lodev09.truesheet.core.Utils
1414
import com.lodev09.truesheet.events.ContainerSizeChangeEvent
1515
import com.lodev09.truesheet.events.DismissEvent
16+
import com.lodev09.truesheet.events.DragEvent
1617
import com.lodev09.truesheet.events.MountEvent
1718
import com.lodev09.truesheet.events.PresentEvent
1819
import com.lodev09.truesheet.events.SizeChangeEvent
@@ -33,6 +34,7 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
3334
.put(PresentEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPresent"))
3435
.put(DismissEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDismiss"))
3536
.put(SizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onSizeChange"))
37+
.put(DragEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDrag"))
3638
.put(ContainerSizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onContainerSizeChange"))
3739
.build()
3840

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.lodev09.truesheet.events
2+
3+
import com.facebook.react.bridge.Arguments
4+
import com.facebook.react.bridge.WritableMap
5+
import com.facebook.react.uimanager.events.Event
6+
import com.lodev09.truesheet.SizeInfo
7+
8+
// onDrag
9+
class DragEvent(surfaceId: Int, viewId: Int, private val state: String, private val sizeInfo: SizeInfo) :
10+
Event<DragEvent>(surfaceId, viewId) {
11+
override fun getEventName() = EVENT_NAME
12+
13+
override fun getEventData(): WritableMap {
14+
val sizeInfoData = Arguments.createMap()
15+
sizeInfoData.putInt("index", sizeInfo.index)
16+
sizeInfoData.putDouble("value", sizeInfo.value.toDouble())
17+
18+
val data = Arguments.createMap()
19+
data.putString("state", state)
20+
data.putMap("sizeInfo", sizeInfoData)
21+
22+
return data
23+
}
24+
25+
companion object {
26+
const val EVENT_NAME = "drag"
27+
}
28+
}

0 commit comments

Comments
 (0)