React Native 0.76.x
#7905 previous topic 0.75.x
The Solution for Android 0.76.1
react-native-navigation\lib\android\app\src\main\java\com\reactnativenavigation\utils\ReactTypefaceUtils.java
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// This file was copied over from react-native
// to provide backwards compatibility < rn 0.62
//
// TODO: Remove me and use com.facebook.react.views.text.ReactTypefaceUtils
// once we drop support for rn < 0.62
package com.reactnativenavigation.utils;
import android.content.res.AssetManager;
import android.graphics.Typeface;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.views.text.ReactFontManager;
import com.facebook.react.common.ReactConstants;
import java.util.ArrayList;
import java.util.List;
public class ReactTypefaceUtils {
public static final int UNSET = -1;
public static int parseFontWeight(@Nullable String fontWeightString) {
int fontWeightNumeric =
fontWeightString != null ? parseNumericFontWeight(fontWeightString) : UNSET;
int fontWeight = fontWeightNumeric != UNSET ? fontWeightNumeric : Typeface.NORMAL;
if (fontWeight == 700 || "bold".equals(fontWeightString)) fontWeight = Typeface.BOLD;
else if (fontWeight == 400 || "normal".equals(fontWeightString)) fontWeight = Typeface.NORMAL;
return fontWeight;
}
public static int parseFontStyle(@Nullable String fontStyleString) {
int fontStyle = UNSET;
if ("italic".equals(fontStyleString)) {
fontStyle = Typeface.ITALIC;
} else if ("normal".equals(fontStyleString)) {
fontStyle = Typeface.NORMAL;
}
return fontStyle;
}
public static @Nullable String parseFontVariant(@Nullable ReadableArray fontVariantArray) {
if (fontVariantArray == null || fontVariantArray.size() == 0) {
return null;
}
List<String> features = new ArrayList<>();
for (int i = 0; i < fontVariantArray.size(); i++) {
// see https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
String fontVariant = fontVariantArray.getString(i);
if (fontVariant != null) {
switch (fontVariant) {
case "small-caps":
features.add("'smcp'");
break;
case "oldstyle-nums":
features.add("'onum'");
break;
case "lining-nums":
features.add("'lnum'");
break;
case "tabular-nums":
features.add("'tnum'");
break;
case "proportional-nums":
features.add("'pnum'");
break;
}
}
}
return TextUtils.join(", ", features);
}
public static Typeface applyStyles(
@Nullable Typeface typeface,
int style,
int weight,
@Nullable String family,
AssetManager assetManager) {
int oldStyle;
if (typeface == null) {
oldStyle = 0;
} else {
oldStyle = typeface.getStyle();
}
int want = 0;
if ((weight == Typeface.BOLD)
|| ((oldStyle & Typeface.BOLD) != 0 && weight == ReactConstants.UNSET)) {
want |= Typeface.BOLD;
}
if ((style == Typeface.ITALIC)
|| ((oldStyle & Typeface.ITALIC) != 0 && style == ReactConstants.UNSET)) {
want |= Typeface.ITALIC;
}
if (family != null) {
typeface = ReactFontManager.getInstance().getTypeface(family, want, weight, assetManager);
} else if (typeface != null) {
// TODO(t9055065): Fix custom fonts getting applied to text children with different style
typeface = Typeface.create(typeface, want);
}
if (typeface != null) {
return typeface;
} else {
return Typeface.defaultFromStyle(want);
}
}
/**
* Return -1 if the input string is not a valid numeric fontWeight (100, 200, ..., 900), otherwise
* return the weight.
*/
private static int parseNumericFontWeight(String fontWeightString) {
// This should be much faster than using regex to verify input and Integer.parseInt
return fontWeightString.length() == 3
&& fontWeightString.endsWith("00")
&& fontWeightString.charAt(0) <= '9'
&& fontWeightString.charAt(0) >= '1'
? 100 * (fontWeightString.charAt(0) - '0')
: UNSET;
}
}
react-native-navigation\lib\android\app\src\main\java\com\reactnativenavigation\utils\ReactViewGroup.kt
package com.reactnativenavigation.utils
import com.facebook.react.views.view.ReactViewBackgroundDrawable
import com.facebook.react.views.view.ReactViewGroup
val ReactViewGroup.borderRadius: Float
get() = 0f
react-native-navigation\lib\android\app\src\main\java\com\reactnativenavigation\viewcontrollers\viewcontroller\LayoutDirectionApplier.kt
package com.reactnativenavigation.viewcontrollers.viewcontroller
import com.facebook.react.ReactInstanceManager
import com.facebook.react.modules.i18nmanager.I18nUtil
import com.reactnativenavigation.options.Options
import com.facebook.react.bridge.ReactContext
class LayoutDirectionApplier {
fun apply(root: ViewController<*>, options: Options, instanceManager: ReactInstanceManager) {
// currentReactContext'in null olup olmadığını kontrol ediyoruz
val reactContext = instanceManager.currentReactContext as? ReactContext
if (options.layout.direction.hasValue() && reactContext != null) {
root.activity.window.decorView.layoutDirection = options.layout.direction.get()
I18nUtil.getInstance().allowRTL(reactContext, options.layout.direction.isRtl)
I18nUtil.getInstance().forceRTL(reactContext, options.layout.direction.isRtl)
}
}
}
https://github.com/wix/react-native-navigation/issues/7930 Hermes Enabled: libhermes_executor.so Hermes Disabled: libjscexecutor.so troubleshooting your mistakes react-native-navigation\lib\android\app\src\main\java\com\reactnativenavigation\NavigationApplication.java
package com.reactnativenavigation;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.soloader.SoLoader;
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
import com.reactnativenavigation.react.ReactGateway;
import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
import java.util.HashMap;
import java.util.Map;
import androidx.annotation.NonNull;
public abstract class NavigationApplication extends Application implements ReactApplication {
private ReactGateway reactGateway;
public static NavigationApplication instance;
final Map<String, ExternalComponentCreator> externalComponents = new HashMap<>();
@Override
public void onCreate() {
super.onCreate();
instance = this;
try {
SoLoader.init(this, OpenSourceMergedSoMapping.INSTANCE);
} catch (Exception e) {
e.printStackTrace();
}
reactGateway = createReactGateway();
}
/**
* Subclasses of NavigationApplication may override this method to create the singleton instance
* of {@link ReactGateway}. For example, subclasses may wish to provide a custom {@link ReactNativeHost}
* with the ReactGateway. This method will be called exactly once, in the application's {@link #onCreate()} method.
*
* Custom {@link ReactNativeHost}s must be sure to include {@link com.reactnativenavigation.react.NavigationPackage}
*
* @return a singleton {@link ReactGateway}
*/
protected ReactGateway createReactGateway() {
return new ReactGateway(getReactNativeHost());
}
public ReactGateway getReactGateway() {
return reactGateway;
}
/**
* Generally no need to override this; override for custom permission handling.
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
}
/**
* Register a native View which can be displayed using the given {@code name}
* @param name Unique name used to register the native view
* @param creator Used to create the view at runtime
*/
@SuppressWarnings("unused")
public void registerExternalComponent(String name, ExternalComponentCreator creator) {
if (externalComponents.containsKey(name)) {
throw new RuntimeException("A component has already been registered with this name: " + name);
}
externalComponents.put(name, creator);
}
public final Map<String, ExternalComponentCreator> getExternalComponents() {
return externalComponents;
}
}
react-native-navigation\lib\android\app\src\reactNative71\java\com\reactnativenavigation\react\modal\ModalContentLayout.kt
package com.reactnativenavigation.react.modal
import android.content.Context
import android.view.MotionEvent
import android.view.View
import com.facebook.react.bridge.*
import com.facebook.react.uimanager.*
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.view.ReactViewGroup
class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView {
private var hasAdjustedSize = false
private var viewWidth = 0
private var viewHeight = 0
private val mJSTouchDispatcher = JSTouchDispatcher(this)
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
viewWidth = w
viewHeight = h
this.updateFirstChildView()
}
private fun updateFirstChildView() {
if (this.childCount > 0) {
hasAdjustedSize = false
val viewTag = getChildAt(0).id
val reactContext: ReactContext = this.getReactContext()
reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) {
override fun runGuarded() {
val uiManager = [email protected]().getNativeModule(
UIManagerModule::class.java
) as UIManagerModule
uiManager.updateNodeSize(
viewTag,
[email protected],
[email protected]
)
}
})
} else {
hasAdjustedSize = true
}
}
override fun addView(child: View?, index: Int, params: LayoutParams?) {
super.addView(child, index, params)
if (hasAdjustedSize) {
updateFirstChildView()
}
}
override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) {
androidEvent?.let {
mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
}
}
override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) {
androidEvent?.let {
mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
}
}
override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) {
androidEvent?.let {
mJSTouchDispatcher.onChildEndedNativeGesture(it, this.getEventDispatcher()!!)
}
}
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
private fun getEventDispatcher(): EventDispatcher? {
val reactContext: ReactContext = this.getReactContext()
return reactContext.getNativeModule(UIManagerModule::class.java)?.eventDispatcher
}
override fun handleException(t: Throwable?) {
getReactContext().handleException(RuntimeException(t))
}
private fun getReactContext(): ReactContext {
return this.context as ReactContext
}
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
event?.let {
mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!)
}
return super.onInterceptTouchEvent(event)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
event?.let {
mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!)
}
super.onTouchEvent(event)
return true
}
}
react-native: 0.76.1 react-native-navigation: 7.40.3 java: 17 node: 22.5.1 gradle: 8.10 buildToolsVersion = "35.0.0" minSdkVersion = 24 (https://github.com/react-native-community/discussions-and-proposals/discussions/802) compileSdkVersion = 35 targetSdkVersion = 35 ndkVersion = "27.0.12077973" kotlinVersion = "2.0.20"
android\gradle.properties newArchEnabled=false RN 0.76.x by default, it comes true. hermesEnabled=true
It has only been tested for Android.
### Tasks
- [ ] https://github.com/wix/react-native-navigation/issues/7905
+1
@ertugruldogan any solution?
RN v0.76.1 or v0.76.2 I can get it resolved. React Native 0.75.x there may be problems, including. It seems as if React-Native-Navigation support is little sought after by the community.
@ertugruldogan are you solve RN V0.76.0 i upgrade from 0.75.4 to 0.76.0 the app crashed when i run it
@ertugruldogan are you solve RN V0.76.0 i upgrade from 0.75.4 to 0.76.0 the app crashed when i run it
Not only react-native-navigation library but also many other libraries are currently incompatible. Error details are needed. I suggest you wait for 0.76.1 and 0.76.2.
@ertugruldogan ok thank you
@ertugruldogan I'm reaching out to check if there have been any updates or changes regarding my issue?!
Any updatrs? And are you looking into enabling the new arch now that is the default?
this work with new arch for android but ios dosnt work with me
The Solution for Android 0.76.1 It has been updated.
ertugruldogan any updates for ios ?
This is great stuff, everyone. We'll get to working on all of this soon, under #7941
The lack of activity on this (not even merging ready to go PRs when the project fails to compile for the last 2 RN releases) simply shows that Wix no longer considers RNN as a priority. We'll probably migrate to React Navigation as a result.
@d4vidi @MohamedAbdElNaby
Is react-native-navigation functioning correctly with React-native 0.76.3? I wasn’t able to make it work on a blank React-native 0.76.3 setup.
https://github.com/rendomnet/repro-bug-rnn