Skip to content

Commit 3b34081

Browse files
committed
wip: rough working state for android
1 parent 38df843 commit 3b34081

File tree

9 files changed

+158
-33
lines changed

9 files changed

+158
-33
lines changed

apps/example/src/Screens/Article.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function Article({
5353
console.log(Platform.OS, ' Rendering Article');
5454
return (
5555
<ScrollView
56+
onLayout={({ nativeEvent: { layout } }) => console.log(layout)}
5657
ref={ref}
5758
style={{ backgroundColor: '#fff' }}
5859
contentContainerStyle={styles.content}

packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import android.util.Log
1212
import android.util.Size
1313
import android.util.TypedValue
1414
import android.view.Choreographer
15+
import android.view.Gravity
1516
import android.view.HapticFeedbackConstants
1617
import android.view.MenuItem
1718
import android.view.View
@@ -72,16 +73,19 @@ class ReactBottomNavigationView(context: Context) : LinearLayout(context) {
7273

7374
addView(
7475
layoutHolder, LayoutParams(
75-
LayoutParams.MATCH_PARENT,
76+
ViewGroup.LayoutParams.MATCH_PARENT,
7677
0,
77-
).apply { weight = 1f }
78+
)
79+
.apply { weight = 1f }
7880
)
7981
layoutHolder.isSaveEnabled = false
8082

8183
addView(bottomNavigation, LayoutParams(
8284
LayoutParams.MATCH_PARENT,
8385
LayoutParams.WRAP_CONTENT
84-
))
86+
).apply {
87+
gravity = Gravity.BOTTOM
88+
})
8589
uiModeConfiguration = resources.configuration.uiMode
8690

8791
post {
@@ -142,9 +146,11 @@ class ReactBottomNavigationView(context: Context) : LinearLayout(context) {
142146
return
143147
}
144148

145-
val container = createContainer()
146-
container.addView(child, params)
147-
layoutHolder.addView(container, index)
149+
// val container = createContainer()
150+
// container.addView(child, params)
151+
child.visibility = GONE
152+
child.isEnabled = false
153+
layoutHolder.addView(child, index)
148154

149155
val itemKey = items[index].key
150156
if (selectedItem == itemKey) {
@@ -153,18 +159,18 @@ class ReactBottomNavigationView(context: Context) : LinearLayout(context) {
153159
}
154160
}
155161

156-
private fun createContainer(): FrameLayout {
157-
val container = FrameLayout(context).apply {
158-
layoutParams = FrameLayout.LayoutParams(
159-
FrameLayout.LayoutParams.MATCH_PARENT,
160-
FrameLayout.LayoutParams.MATCH_PARENT
161-
)
162-
isSaveEnabled = false
163-
visibility = GONE
164-
isEnabled = false
165-
}
166-
return container
167-
}
162+
// private fun createContainer(): FrameLayout {
163+
// val container = FrameLayout(context).apply {
164+
// layoutParams = FrameLayout.LayoutParams(
165+
// FrameLayout.LayoutParams.MATCH_PARENT,
166+
// FrameLayout.LayoutParams.MATCH_PARENT
167+
// )
168+
// isSaveEnabled = false
169+
// visibility = GONE
170+
// isEnabled = false
171+
// }
172+
// return container
173+
// }
168174

169175
private fun setSelectedIndex(itemId: Int) {
170176
bottomNavigation.selectedItemId = itemId

packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabViewPackage.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class RCTTabViewPackage : ReactPackage {
1010
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
1111
val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
1212
viewManagers.add(RCTTabViewManager(reactContext))
13+
viewManagers.add(RCTTabViewScreenManager(reactContext))
1314
return viewManagers
1415
}
1516

packages/react-native-bottom-tabs/android/src/main/jni/RNCTabView.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <ReactCommon/JavaTurboModule.h>
44
#include <ReactCommon/TurboModule.h>
55
#include <jsi/jsi.h>
6-
#include <react/renderer/components/RNCTabView/RNCTabViewComponentDescriptor.h>
6+
#include <react/renderer/components/RNCTabView/RNCTabViewScreenComponentDescriptor.h>
77

88
namespace facebook::react {
99
JSI_EXPORT

packages/react-native-bottom-tabs/android/src/newarch/RCTTabViewManager.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.rcttabview
22

3+
import android.util.Log
34
import android.view.View
4-
import android.view.ViewGroup
5+
import android.widget.FrameLayout
6+
import androidx.core.view.children
57
import com.facebook.react.bridge.ReactApplicationContext
68
import com.facebook.react.bridge.ReadableArray
79
import com.facebook.react.module.annotations.ReactModule
@@ -11,7 +13,6 @@ import com.facebook.react.uimanager.ViewGroupManager
1113
import com.facebook.react.uimanager.ViewManagerDelegate
1214
import com.facebook.react.viewmanagers.RNCTabViewManagerDelegate
1315
import com.facebook.react.viewmanagers.RNCTabViewManagerInterface
14-
import com.rcttabview.events.OnNativeLayoutEvent
1516
import com.rcttabview.events.PageSelectedEvent
1617
import com.rcttabview.events.TabLongPressEvent
1718

@@ -36,9 +37,21 @@ class RCTTabViewManager(context: ReactApplicationContext) :
3637
eventDispatcher?.dispatchEvent(TabLongPressEvent(viewTag = view.id, key))
3738
}
3839

39-
view.onNativeLayoutListener = { width, height ->
40-
eventDispatcher?.dispatchEvent(OnNativeLayoutEvent(viewTag = view.id, width, height))
41-
}
40+
// view.onNativeLayoutListener = { width, height ->
41+
// val childCount = tabViewImpl.getChildCount(view)
42+
// for (i in 0 until childCount) { // Use 'until' instead of '..' to exclude childCount
43+
// val child = tabViewImpl.getChildAt(view, i)
44+
//
45+
// // Safe cast for FrameLayout
46+
// if (child is RCTTabViewScreen) {
47+
// child.updateFrame(width, height)
48+
//
49+
// Log.w("TAB_VIEW", "CHILD: ${child}")
50+
// }
51+
// }
52+
//
53+
//// eventDispatcher?.dispatchEvent(OnNativeLayoutEvent(viewTag = view.id, width, height))
54+
// }
4255
return view
4356

4457
}
@@ -72,9 +85,9 @@ class RCTTabViewManager(context: ReactApplicationContext) :
7285
tabViewImpl.removeViewAt(parent, index)
7386
}
7487

75-
override fun needsCustomLayoutForChildren(): Boolean {
76-
return tabViewImpl.needsCustomLayoutForChildren()
77-
}
88+
// override fun needsCustomLayoutForChildren(): Boolean {
89+
// return tabViewImpl.needsCustomLayoutForChildren()
90+
// }
7891

7992
override fun setItems(view: ReactBottomNavigationView?, value: ReadableArray?) {
8093
if (view != null && value != null)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.rcttabview
2+
3+
import android.content.Context
4+
import android.os.Build
5+
import android.util.Log
6+
import android.view.View
7+
import android.view.WindowInsets
8+
import android.view.WindowManager
9+
import android.widget.FrameLayout
10+
import androidx.core.view.ViewCompat
11+
import androidx.core.view.WindowInsetsCompat
12+
import com.facebook.react.bridge.Arguments
13+
import com.facebook.react.bridge.ReactApplicationContext
14+
import com.facebook.react.module.annotations.ReactModule
15+
import com.facebook.react.uimanager.ReactStylesDiffMap
16+
import com.facebook.react.uimanager.StateWrapper
17+
import com.facebook.react.uimanager.ThemedReactContext
18+
import com.facebook.react.uimanager.ViewGroupManager
19+
import com.facebook.react.uimanager.ViewManagerDelegate
20+
import com.facebook.react.viewmanagers.RNCTabViewScreenManagerDelegate
21+
import com.facebook.react.viewmanagers.RNCTabViewScreenManagerInterface
22+
import com.facebook.react.views.view.ReactViewGroup
23+
24+
class RCTTabViewScreen(context: Context): ReactViewGroup(context) {
25+
private var stateWrapper: StateWrapper? = null
26+
27+
public fun setStateWrapper(stateWrapper: StateWrapper?) {
28+
this.stateWrapper = stateWrapper
29+
}
30+
31+
init {
32+
getSystemInsets(this) { left, top, right, bottom ->
33+
Log.w("TAB_VIEW", "${left} ${top} ${right} ${bottom}")
34+
35+
stateWrapper?.updateState(Arguments.createMap().apply {
36+
putDouble("width", Utils.convertPixelsToDp(context, width))
37+
putDouble("height", Utils.convertPixelsToDp(context, height - bottom))
38+
})
39+
}
40+
}
41+
42+
fun getSystemInsets(view: View, callback: (left: Int, top: Int, right: Int, bottom: Int) -> Unit) {
43+
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
44+
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
45+
callback(
46+
systemBars.left, // Left inset (for left-aligned Navigation Rail)
47+
systemBars.top, // Top inset
48+
systemBars.right, // Right inset (for right-aligned Navigation Rail)
49+
systemBars.bottom // Bottom inset (for bottom navigation)
50+
)
51+
insets
52+
}
53+
// Ensure we request insets
54+
if (view.isAttachedToWindow) {
55+
ViewCompat.requestApplyInsets(view)
56+
} else {
57+
view.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
58+
override fun onViewAttachedToWindow(v: View) {
59+
ViewCompat.requestApplyInsets(v)
60+
v.removeOnAttachStateChangeListener(this)
61+
}
62+
override fun onViewDetachedFromWindow(v: View) = Unit
63+
})
64+
}
65+
}
66+
}
67+
68+
69+
@ReactModule(name = "RNCTabViewScreen")
70+
class RCTTabViewScreenManager(context: ReactApplicationContext) :
71+
ViewGroupManager<RCTTabViewScreen>(),
72+
RNCTabViewScreenManagerInterface<RCTTabViewScreen> {
73+
74+
private val delegate: RNCTabViewScreenManagerDelegate<RCTTabViewScreen, RCTTabViewScreenManager> =
75+
RNCTabViewScreenManagerDelegate(this)
76+
77+
78+
override fun createViewInstance(context: ThemedReactContext): RCTTabViewScreen {
79+
return RCTTabViewScreen(context);
80+
}
81+
82+
override fun updateState(
83+
view: RCTTabViewScreen,
84+
props: ReactStylesDiffMap?,
85+
stateWrapper: StateWrapper?
86+
): Any? {
87+
view.setStateWrapper(stateWrapper)
88+
return super.updateState(view, props, stateWrapper)
89+
}
90+
91+
override fun getDelegate(): ViewManagerDelegate<RCTTabViewScreen> {
92+
return delegate
93+
}
94+
95+
override fun getName(): String {
96+
return "RNCTabViewScreen"
97+
}
98+
}

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewScreenComponentDescriptor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ class RNCTabViewScreenComponentDescriptor final : public ConcreteComponentDescri
1313
RNCTabViewScreenComponentDescriptor(const ComponentDescriptorParameters &parameters)
1414
: ConcreteComponentDescriptor(parameters) {}
1515

16-
16+
1717
/**
1818
Retrieve shadow node's state and update it's layout size accordingly.
1919
This is needed because we need to accomodate for bottom bar / sidebar size.
2020
*/
2121
void adopt(ShadowNode &shadowNode) const override {
2222
auto& layoutableShadowNode = static_cast<RNCTabViewScreenShadowNode&>(shadowNode);
2323
auto& stateData = layoutableShadowNode.getStateData();
24-
24+
2525
layoutableShadowNode.setSize(stateData.frameSize);
26-
26+
2727
ConcreteComponentDescriptor::adopt(shadowNode);
2828
}
2929
};

packages/react-native-bottom-tabs/common/cpp/react/renderer/components/RNCTabView/RNCTabViewScreenState.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#include <react/renderer/graphics/Size.h>
55
#ifdef ANDROID
66
#include <folly/dynamic.h>
7-
#include <react/renderer/mapbuffer/MapBuffer.h>
8-
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
97
#endif
108

119
namespace facebook::react {
@@ -17,6 +15,14 @@ class RNCTabViewScreenState
1715
RNCTabViewScreenState(Size frameSize): frameSize(frameSize) {};
1816

1917
Size frameSize;
18+
19+
#ifdef ANDROID
20+
RNCTabViewScreenState(RNCTabViewScreenState const &previousState, folly::dynamic data)
21+
: frameSize((Float)data["width"].getDouble(), (Float)data["height"].getDouble()) {};
22+
folly::dynamic getDynamic() const {
23+
return {};
24+
};
25+
#endif
2026
};
2127

2228
}

packages/react-native-bottom-tabs/react-native.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module.exports = {
33
platforms: {
44
android: {
55
libraryName: 'RNCTabView',
6-
componentDescriptors: ['RNCTabViewComponentDescriptor'],
6+
componentDescriptors: ['RNCTabViewScreenComponentDescriptor'],
77
cmakeListsPath: 'src/main/jni/CMakeLists.txt',
88
},
99
},

0 commit comments

Comments
 (0)