@onekeyfe/react-native-pager-view 3.0.114 → 3.0.116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt +630 -0
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerViewManager.kt +222 -0
- package/android/src/main/java/com/reactnativepagerview/NestedScrollableHost.kt +3 -1
- package/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +1 -1
- package/android/src/main/java/com/reactnativepagerview/event/CollapsibleStateChangedEvent.kt +39 -0
- package/ios/RNCCollapsiblePagerViewComponentView.h +9 -0
- package/ios/RNCCollapsiblePagerViewComponentView.mm +991 -0
- package/ios/RNCPagerViewComponentView.mm +4 -2
- package/lib/module/CollapsiblePagerView.js +167 -0
- package/lib/module/CollapsiblePagerView.web.js +478 -0
- package/lib/module/CollapsiblePagerViewNativeComponent.ts +87 -0
- package/lib/module/PagerView.web.js +177 -0
- package/lib/module/index.js +2 -1
- package/lib/module/index.web.js +6 -0
- package/lib/module/usePagerView.js +1 -1
- package/lib/typescript/src/CollapsiblePagerView.d.ts +58 -0
- package/lib/typescript/src/CollapsiblePagerView.web.d.ts +105 -0
- package/lib/typescript/src/CollapsiblePagerViewNativeComponent.d.ts +51 -0
- package/lib/typescript/src/PagerView.web.d.ts +55 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.web.d.ts +5 -0
- package/package.json +5 -2
- package/src/CollapsiblePagerView.tsx +293 -0
- package/src/CollapsiblePagerView.web.tsx +710 -0
- package/src/CollapsiblePagerViewNativeComponent.ts +87 -0
- package/src/PagerView.web.tsx +280 -0
- package/src/index.tsx +1 -0
- package/src/index.web.tsx +12 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
package com.reactnativepagerview
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import androidx.viewpager2.widget.ViewPager2
|
|
6
|
+
import com.facebook.react.bridge.ReadableArray
|
|
7
|
+
import com.facebook.react.common.MapBuilder
|
|
8
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
9
|
+
import com.facebook.react.uimanager.PixelUtil
|
|
10
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
12
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
13
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
14
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
15
|
+
import com.facebook.react.viewmanagers.RNCCollapsiblePagerViewManagerDelegate
|
|
16
|
+
import com.facebook.react.viewmanagers.RNCCollapsiblePagerViewManagerInterface
|
|
17
|
+
import com.reactnativepagerview.event.CollapsibleStateChangedEvent
|
|
18
|
+
import com.reactnativepagerview.event.PageScrollEvent
|
|
19
|
+
import com.reactnativepagerview.event.PageScrollStateChangedEvent
|
|
20
|
+
import com.reactnativepagerview.event.PageSelectedEvent
|
|
21
|
+
import org.json.JSONArray
|
|
22
|
+
import kotlin.math.roundToInt
|
|
23
|
+
|
|
24
|
+
@ReactModule(name = CollapsiblePagerViewManager.NAME)
|
|
25
|
+
class CollapsiblePagerViewManager : ViewGroupManager<CollapsiblePagerHost>(),
|
|
26
|
+
RNCCollapsiblePagerViewManagerInterface<CollapsiblePagerHost> {
|
|
27
|
+
|
|
28
|
+
private val delegate: ViewManagerDelegate<CollapsiblePagerHost> =
|
|
29
|
+
RNCCollapsiblePagerViewManagerDelegate(this)
|
|
30
|
+
|
|
31
|
+
override fun getDelegate() = delegate
|
|
32
|
+
|
|
33
|
+
override fun getName() = NAME
|
|
34
|
+
|
|
35
|
+
override fun createViewInstance(reactContext: ThemedReactContext): CollapsiblePagerHost {
|
|
36
|
+
val host = CollapsiblePagerHost(reactContext)
|
|
37
|
+
host.id = View.generateViewId()
|
|
38
|
+
host.layoutParams = ViewGroup.LayoutParams(
|
|
39
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
40
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
41
|
+
)
|
|
42
|
+
host.pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
|
43
|
+
override fun onPageScrolled(position: Int, offset: Float, offsetPixels: Int) {
|
|
44
|
+
dispatch(reactContext, host, PageScrollEvent(host.id, position, offset))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun onPageSelected(position: Int) {
|
|
48
|
+
host.selectPage(position)
|
|
49
|
+
dispatch(reactContext, host, PageSelectedEvent(host.id, position))
|
|
50
|
+
dispatchDiagnostics(reactContext, host, "page-selected")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override fun onPageScrollStateChanged(state: Int) {
|
|
54
|
+
val value = when (state) {
|
|
55
|
+
ViewPager2.SCROLL_STATE_IDLE -> "idle"
|
|
56
|
+
ViewPager2.SCROLL_STATE_DRAGGING -> "dragging"
|
|
57
|
+
ViewPager2.SCROLL_STATE_SETTLING -> "settling"
|
|
58
|
+
else -> return
|
|
59
|
+
}
|
|
60
|
+
dispatch(reactContext, host, PageScrollStateChangedEvent(host.id, value))
|
|
61
|
+
if (state == ViewPager2.SCROLL_STATE_IDLE) {
|
|
62
|
+
dispatchDiagnostics(reactContext, host, "pager-idle")
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
host.onHeaderOffsetChanged = {
|
|
67
|
+
if (!host.pager.isFakeDragging && host.pager.scrollState == ViewPager2.SCROLL_STATE_IDLE) {
|
|
68
|
+
dispatchDiagnostics(reactContext, host, "vertical-idle")
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
host.post {
|
|
72
|
+
dispatch(reactContext, host, PageSelectedEvent(host.id, host.pager.currentItem))
|
|
73
|
+
dispatchDiagnostics(reactContext, host, "mounted")
|
|
74
|
+
}
|
|
75
|
+
return host
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private fun dispatch(reactContext: ThemedReactContext, host: CollapsiblePagerHost, event: com.facebook.react.uimanager.events.Event<*>) {
|
|
79
|
+
UIManagerHelper.getEventDispatcherForReactTag(reactContext, host.id)?.dispatchEvent(event)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private fun dispatchDiagnostics(
|
|
83
|
+
reactContext: ThemedReactContext,
|
|
84
|
+
host: CollapsiblePagerHost,
|
|
85
|
+
reason: String,
|
|
86
|
+
) {
|
|
87
|
+
dispatch(
|
|
88
|
+
reactContext,
|
|
89
|
+
host,
|
|
90
|
+
CollapsibleStateChangedEvent(
|
|
91
|
+
host.id,
|
|
92
|
+
host.selectedPage,
|
|
93
|
+
PixelUtil.toDIPFromPixel(host.headerOffsetPx.toFloat()).toDouble(),
|
|
94
|
+
host.adapter.itemCount,
|
|
95
|
+
host.attachedPageCount(),
|
|
96
|
+
host.observedScrollableCount(),
|
|
97
|
+
host.retainedPages,
|
|
98
|
+
reason,
|
|
99
|
+
),
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
override fun addView(parent: CollapsiblePagerHost, child: View, index: Int) =
|
|
104
|
+
parent.addReactChild(child, index)
|
|
105
|
+
|
|
106
|
+
override fun getChildCount(parent: CollapsiblePagerHost) = parent.reactChildCount()
|
|
107
|
+
|
|
108
|
+
override fun getChildAt(parent: CollapsiblePagerHost, index: Int) = parent.reactChildAt(index)
|
|
109
|
+
|
|
110
|
+
override fun removeView(parent: CollapsiblePagerHost, view: View) = parent.removeReactChild(view)
|
|
111
|
+
|
|
112
|
+
override fun removeViewAt(parent: CollapsiblePagerHost, index: Int) =
|
|
113
|
+
parent.removeReactChild(parent.reactChildAt(index))
|
|
114
|
+
|
|
115
|
+
override fun removeAllViews(parent: CollapsiblePagerHost) = parent.removeAllReactChildren()
|
|
116
|
+
|
|
117
|
+
override fun needsCustomLayoutForChildren() = true
|
|
118
|
+
|
|
119
|
+
@ReactProp(name = "scrollEnabled", defaultBoolean = true)
|
|
120
|
+
override fun setScrollEnabled(view: CollapsiblePagerHost?, value: Boolean) {
|
|
121
|
+
view?.pager?.isUserInputEnabled = value
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@ReactProp(name = "layoutDirection")
|
|
125
|
+
override fun setLayoutDirection(view: CollapsiblePagerHost?, value: String?) {
|
|
126
|
+
view?.pager?.layoutDirection = if (value == "rtl") {
|
|
127
|
+
View.LAYOUT_DIRECTION_RTL
|
|
128
|
+
} else {
|
|
129
|
+
View.LAYOUT_DIRECTION_LTR
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@ReactProp(name = "initialPage", defaultInt = 0)
|
|
134
|
+
override fun setInitialPage(view: CollapsiblePagerHost?, value: Int) {
|
|
135
|
+
view ?: return
|
|
136
|
+
view.pendingInitialPage = value
|
|
137
|
+
view.applyPendingInitialPage()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@ReactProp(name = "offscreenPageLimit", defaultInt = ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT)
|
|
141
|
+
override fun setOffscreenPageLimit(view: CollapsiblePagerHost?, value: Int) {
|
|
142
|
+
view?.pager?.offscreenPageLimit = if (value == ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT) {
|
|
143
|
+
value
|
|
144
|
+
} else {
|
|
145
|
+
value.coerceAtLeast(1)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@ReactProp(name = "nestedScrollEnabled", defaultBoolean = false)
|
|
150
|
+
override fun setNestedScrollEnabled(view: CollapsiblePagerHost?, value: Boolean) {
|
|
151
|
+
// OneKey patch: CollapsiblePagerHost always coordinates nested pagers on Android.
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// OneKey patch: round Yoga header dimensions to the nearest physical pixel.
|
|
155
|
+
@ReactProp(name = "headerHeight", defaultInt = 0)
|
|
156
|
+
override fun setHeaderHeight(view: CollapsiblePagerHost?, value: Int) {
|
|
157
|
+
view?.headerHeightPx = PixelUtil.toPixelFromDIP(value.toDouble()).roundToInt()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@ReactProp(name = "stickyHeaderHeight", defaultInt = 0)
|
|
161
|
+
override fun setStickyHeaderHeight(view: CollapsiblePagerHost?, value: Int) {
|
|
162
|
+
view?.stickyHeaderHeightPx = PixelUtil.toPixelFromDIP(value.toDouble()).roundToInt()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@ReactProp(name = "pageKeys")
|
|
166
|
+
override fun setPageKeys(view: CollapsiblePagerHost?, value: String?) {
|
|
167
|
+
view ?: return
|
|
168
|
+
view.pageKeys = parseStringArray(value)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@ReactProp(name = "retainedPages")
|
|
172
|
+
override fun setRetainedPages(view: CollapsiblePagerHost?, value: String?) {
|
|
173
|
+
view?.retainedPages = value ?: "[]"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private fun parseStringArray(value: String?): List<String> {
|
|
177
|
+
if (value.isNullOrEmpty()) return emptyList()
|
|
178
|
+
return runCatching {
|
|
179
|
+
val json = JSONArray(value)
|
|
180
|
+
List(json.length()) { index -> json.optString(index, "page-$index") }
|
|
181
|
+
}.getOrDefault(emptyList())
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
override fun receiveCommand(root: CollapsiblePagerHost, commandId: String, args: ReadableArray?) {
|
|
185
|
+
delegate.receiveCommand(root, commandId, args)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override fun setPage(view: CollapsiblePagerHost?, selectedPage: Int) {
|
|
189
|
+
if (view != null && selectedPage in 0 until view.adapter.itemCount) {
|
|
190
|
+
view.pager.setCurrentItem(selectedPage, true)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun setPageWithoutAnimation(view: CollapsiblePagerHost?, selectedPage: Int) {
|
|
195
|
+
if (view != null && selectedPage in 0 until view.adapter.itemCount) {
|
|
196
|
+
view.pager.setCurrentItem(selectedPage, false)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
override fun setScrollEnabledImperatively(view: CollapsiblePagerHost?, scrollEnabled: Boolean) {
|
|
201
|
+
view?.pager?.isUserInputEnabled = scrollEnabled
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Map<String, String>> =
|
|
205
|
+
MapBuilder.builder<String, Map<String, String>>()
|
|
206
|
+
.put(PageScrollEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageScroll"))
|
|
207
|
+
.put(PageSelectedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageSelected"))
|
|
208
|
+
.put(
|
|
209
|
+
PageScrollStateChangedEvent.EVENT_NAME,
|
|
210
|
+
MapBuilder.of("registrationName", "onPageScrollStateChanged"),
|
|
211
|
+
)
|
|
212
|
+
.put(
|
|
213
|
+
CollapsibleStateChangedEvent.EVENT_NAME,
|
|
214
|
+
MapBuilder.of("registrationName", "onCollapsibleStateChanged"),
|
|
215
|
+
)
|
|
216
|
+
.build()
|
|
217
|
+
.toMutableMap()
|
|
218
|
+
|
|
219
|
+
companion object {
|
|
220
|
+
const val NAME = "RNCCollapsiblePagerView"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -21,7 +21,9 @@ import kotlin.math.sign
|
|
|
21
21
|
* Supports multiple levels of nested PagerViews by re-asserting
|
|
22
22
|
* requestDisallowInterceptTouchEvent after child dispatch.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
// OneKey patch: Let the collapsible pager reuse same-direction nested pager coordination.
|
|
25
|
+
// Original: class NestedScrollableHost : FrameLayout {
|
|
26
|
+
open class NestedScrollableHost : FrameLayout {
|
|
25
27
|
constructor(context: Context) : super(context)
|
|
26
28
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
|
27
29
|
public var initialIndex: Int? = null
|
|
@@ -12,6 +12,6 @@ class PagerViewPackage : ReactPackage {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
-
return listOf(PagerViewViewManager())
|
|
15
|
+
return listOf(PagerViewViewManager(), CollapsiblePagerViewManager())
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package com.reactnativepagerview.event
|
|
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.facebook.react.uimanager.events.RCTEventEmitter
|
|
7
|
+
|
|
8
|
+
class CollapsibleStateChangedEvent(
|
|
9
|
+
viewTag: Int,
|
|
10
|
+
private val position: Int,
|
|
11
|
+
private val headerOffset: Double,
|
|
12
|
+
private val nativePageCount: Int,
|
|
13
|
+
private val attachedPageCount: Int,
|
|
14
|
+
private val observedScrollableCount: Int,
|
|
15
|
+
private val retainedPages: String,
|
|
16
|
+
private val reason: String,
|
|
17
|
+
) : Event<CollapsibleStateChangedEvent>(viewTag) {
|
|
18
|
+
override fun getEventName() = EVENT_NAME
|
|
19
|
+
|
|
20
|
+
override fun canCoalesce() = false
|
|
21
|
+
|
|
22
|
+
override fun dispatch(rctEventEmitter: RCTEventEmitter) {
|
|
23
|
+
rctEventEmitter.receiveEvent(viewTag, eventName, serializeEventData())
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private fun serializeEventData(): WritableMap = Arguments.createMap().apply {
|
|
27
|
+
putInt("position", position)
|
|
28
|
+
putDouble("headerOffset", headerOffset)
|
|
29
|
+
putInt("nativePageCount", nativePageCount)
|
|
30
|
+
putInt("attachedPageCount", attachedPageCount)
|
|
31
|
+
putInt("observedScrollableCount", observedScrollableCount)
|
|
32
|
+
putString("retainedPages", retainedPages)
|
|
33
|
+
putString("reason", reason)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
companion object {
|
|
37
|
+
const val EVENT_NAME = "topCollapsibleStateChanged"
|
|
38
|
+
}
|
|
39
|
+
}
|