diff --git a/.changeset/two-lobsters-exercise.md b/.changeset/two-lobsters-exercise.md new file mode 100644 index 00000000..b6c9802e --- /dev/null +++ b/.changeset/two-lobsters-exercise.md @@ -0,0 +1,5 @@ +--- +'react-native-bottom-tabs': patch +--- + +fix crash when change tab bar label during runtime diff --git a/apps/example/src/Examples/NativeBottomTabs.tsx b/apps/example/src/Examples/NativeBottomTabs.tsx index b5b81f60..b83332b0 100644 --- a/apps/example/src/Examples/NativeBottomTabs.tsx +++ b/apps/example/src/Examples/NativeBottomTabs.tsx @@ -4,10 +4,12 @@ import { Contacts } from '../Screens/Contacts'; import { Chat } from '../Screens/Chat'; import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation'; import { Platform } from 'react-native'; +import { useState } from 'react'; const Tab = createNativeBottomTabNavigator(); function NativeBottomTabs() { + const [label, setLabel] = useState('Article'); return ( focused ? require('../../assets/icons/person_dark.png') diff --git a/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt b/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt index 61bad386..6bf87658 100644 --- a/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt +++ b/packages/react-native-bottom-tabs/android/src/main/java/com/rcttabview/RCTTabView.kt @@ -197,7 +197,7 @@ class ReactBottomNavigationView(context: ReactContext) : LinearLayout(context) { } private fun onTabSelected(item: MenuItem) { - val selectedItem = items.first { it.title == item.title } + val selectedItem = items[item.itemId] selectedItem.let { onTabSelectedListener?.invoke(selectedItem.key) emitHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK) @@ -205,8 +205,8 @@ class ReactBottomNavigationView(context: ReactContext) : LinearLayout(context) { } private fun onTabLongPressed(item: MenuItem) { - val longPressedItem = items.firstOrNull { it.title == item.title } - longPressedItem?.let { + val longPressedItem = items[item.itemId] + longPressedItem.let { onTabLongPressedListener?.invoke(longPressedItem.key) emitHapticFeedback(HapticFeedbackConstants.LONG_PRESS) } @@ -220,6 +220,10 @@ class ReactBottomNavigationView(context: ReactContext) : LinearLayout(context) { this.items = items items.forEachIndexed { index, item -> val menuItem = getOrCreateItem(index, item.title) + if (item.title !== menuItem.title) { + menuItem.title = item.title + } + menuItem.isVisible = !item.hidden if (iconSources.containsKey(index)) { getDrawable(iconSources[index]!!) { @@ -370,7 +374,7 @@ class ReactBottomNavigationView(context: ReactContext) : LinearLayout(context) { private fun updateTextAppearance() { if (fontSize != null || fontFamily != null || fontWeight != null) { - val menuView = getChildAt(0) as? ViewGroup ?: return + val menuView = bottomNavigation.getChildAt(0) as? ViewGroup ?: return val size = fontSize?.toFloat()?.takeIf { it > 0 } ?: 12f val typeface = ReactFontManager.getInstance().getTypeface( fontFamily ?: "", @@ -403,7 +407,9 @@ class ReactBottomNavigationView(context: ReactContext) : LinearLayout(context) { private fun updateTintColors(item: MenuItem? = null) { // First let's check current item color. - val currentItemTintColor = items.find { it.title == item?.title }?.activeTintColor + val currentItemTintColor = item?.itemId?.let { itemId -> + items[itemId].activeTintColor + } // getDefaultColor will always return a valid color but to satisfy the compiler we need to check for null val colorPrimary = currentItemTintColor ?: activeTintColor ?: Utils.getDefaultColorFor(