<lambda>null1 package com.reactnativepagerview
2
3 import android.view.View
4 import androidx.viewpager2.widget.ViewPager2
5 import com.facebook.react.uimanager.PixelUtil
6
7 object PagerViewViewManagerImpl {
8 const val NAME = "RNCViewPager"
9
10 fun getViewPager(view: NestedScrollableHost): ViewPager2 {
11 if (view.getChildAt(0) is ViewPager2) {
12 return view.getChildAt(0) as ViewPager2
13 } else {
14 throw ClassNotFoundException("Could not retrieve ViewPager2 instance")
15 }
16 }
17
18 fun setCurrentItem(view: ViewPager2, selectedTab: Int, scrollSmooth: Boolean) {
19 refreshViewChildrenLayout(view)
20 view.setCurrentItem(selectedTab, scrollSmooth)
21 }
22
23 fun addView(host: NestedScrollableHost, child: View?, index: Int) {
24 if (child == null) {
25 return
26 }
27 val parent = getViewPager(host)
28
29 (parent.adapter as ViewPagerAdapter?)?.addChild(child, index);
30
31 if (parent.currentItem == index) {
32 // Solves https://github.com/callstack/react-native-pager-view/issues/219
33 // Required so ViewPager actually displays first dynamically added child
34 // (otherwise a white screen is shown until the next user interaction).
35 // https://github.com/facebook/react-native/issues/17968#issuecomment-697136929
36 refreshViewChildrenLayout(parent)
37 }
38
39 if (!host.didSetInitialIndex && host.initialIndex == index) {
40 host.didSetInitialIndex = true
41 setCurrentItem(parent, index, false)
42 }
43 }
44
45 fun getChildCount(parent: NestedScrollableHost) = getViewPager(parent).adapter?.itemCount ?: 0
46
47 fun getChildAt(parent: NestedScrollableHost, index: Int): View {
48 val view = getViewPager(parent)
49 return (view.adapter as ViewPagerAdapter?)!!.getChildAt(index)
50 }
51
52 fun removeView(parent: NestedScrollableHost, view: View) {
53 val pager = getViewPager(parent)
54 (pager.adapter as ViewPagerAdapter?)?.removeChild(view)
55
56 // Required so ViewPager actually animates the removed view right away (otherwise
57 // a white screen is shown until the next user interaction).
58 // https://github.com/facebook/react-native/issues/17968#issuecomment-697136929
59 refreshViewChildrenLayout(pager)
60 }
61
62 fun removeAllViews(parent: NestedScrollableHost) {
63 val pager = getViewPager(parent)
64 pager.isUserInputEnabled = false
65 val adapter = pager.adapter as ViewPagerAdapter?
66 adapter?.removeAll()
67 }
68
69 fun removeViewAt(parent: NestedScrollableHost, index: Int) {
70 val pager = getViewPager(parent)
71 val adapter = pager.adapter as ViewPagerAdapter?
72 adapter?.removeChildAt(index)
73
74 // Required so ViewPager actually animates the removed view right away (otherwise
75 // a white screen is shown until the next user interaction).
76 // https://github.com/facebook/react-native/issues/17968#issuecomment-697136929
77 refreshViewChildrenLayout(pager)
78 }
79
80 fun needsCustomLayoutForChildren(): Boolean {
81 return true
82 }
83
84 fun setScrollEnabled(host: NestedScrollableHost, value: Boolean) {
85 getViewPager(host).isUserInputEnabled = value
86 }
87
88 fun setLayoutDirection(host: NestedScrollableHost, value: String) {
89 val view = getViewPager(host)
90 when (value) {
91 "rtl" -> {
92 view.layoutDirection = View.LAYOUT_DIRECTION_RTL
93 }
94 else -> {
95 view.layoutDirection = View.LAYOUT_DIRECTION_LTR
96 }
97 }
98 }
99
100 fun setInitialPage(host: NestedScrollableHost, value: Int) {
101 val view = getViewPager(host)
102 //https://github.com/callstack/react-native-pager-view/issues/456
103 //Initial index should be set only once.
104 if (host.initialIndex === null) {
105 host.initialIndex = value
106 view.post {
107 host.didSetInitialIndex = true
108 }
109 }
110 }
111
112 fun setOrientation(host: NestedScrollableHost, value: String) {
113 getViewPager(host).orientation = if (value == "vertical") ViewPager2.ORIENTATION_VERTICAL else ViewPager2.ORIENTATION_HORIZONTAL
114 }
115
116 fun setOffscreenPageLimit(host: NestedScrollableHost, value: Int) {
117 getViewPager(host).offscreenPageLimit = value
118 }
119
120 fun setOverScrollMode(host: NestedScrollableHost, value: String) {
121 val child = getViewPager(host).getChildAt(0)
122 when (value) {
123 "never" -> {
124 child.overScrollMode = ViewPager2.OVER_SCROLL_NEVER
125 }
126 "always" -> {
127 child.overScrollMode = ViewPager2.OVER_SCROLL_ALWAYS
128 }
129 else -> {
130 child.overScrollMode = ViewPager2.OVER_SCROLL_IF_CONTENT_SCROLLS
131 }
132 }
133 }
134
135 fun setPageMargin(host: NestedScrollableHost, margin: Int) {
136 val pager = getViewPager(host)
137 val pageMargin = PixelUtil.toPixelFromDIP(margin.toDouble()).toInt()
138 /**
139 * Don't use MarginPageTransformer to be able to support negative margins
140 */
141 pager.setPageTransformer { page, position ->
142 val offset = pageMargin * position
143 if (pager.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
144 val isRTL = pager.layoutDirection == View.LAYOUT_DIRECTION_RTL
145 page.translationX = if (isRTL) -offset else offset
146 } else {
147 page.translationY = offset
148 }
149 }
150 }
151
152 private fun refreshViewChildrenLayout(view: View) {
153 view.post {
154 view.measure(
155 View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY),
156 View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY))
157 view.layout(view.left, view.top, view.right, view.bottom)
158 }
159 }
160 }