I am a beginner so please bear with me.
I am trying to create a Java app which has a React Native instance with Stack Navigator embedded inside it using Java FrameLayout by following some tutorials and this documentation. https://reactnative.dev/docs/integration-with-android-fragment
The thing is, I am able to embed the said React Native instance in the Java app inside FrameLayout and the Home page of the app RN Stack Navigator loads correctly. But when I click on the button to redirect to a new page, the UI doesnt update to reflect the change. I am saying that the UI doesn't change because according to console logs the new screen is being called and rendered too as I can interact with the components which should be in the new screen but aren't visible because the UI doesn't change. The React Native Stack Navigator app works as intended independently though.
This is my "MainActivity.java" File:-
package com.allforone;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void loadReact(View view){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.react_holder, new ReactFragment());
fragmentTransaction.commit();
}
}
This is my "ReactFragment.java" file :-
package com.allforone;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
public class ReactFragment extends Fragment implements DefaultLifecycleObserver {
private ReactRootView reactRootView;
private ReactInstanceManager reactInstanceManager;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
reactRootView = new ReactRootView(requireContext());
reactInstanceManager = ((MainApplication) requireActivity().getApplication()).getReactNativeHost().getReactInstanceManager();
return reactRootView;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
reactRootView = new ReactRootView(requireContext());
reactInstanceManager = ((MainApplication) requireActivity().getApplication()).getReactNativeHost().getReactInstanceManager();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLifecycle().addObserver(this);
}
@Override
public void onDestroy() {
super.onDestroy();
getLifecycle().removeObserver(this);
}
@Override
public void onResume() {
super.onResume();
reactRootView.startReactApplication(reactInstanceManager, "clitest", null);
}
@Override
public void onPause() {
super.onPause();
reactRootView.unmountReactApplication();
}
@Override
public void onStop() {
super.onStop();
reactRootView.unmountReactApplication();
}
}
This is my "MainApplication.java" file
package com.allforone;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}
And finally, my main.xml for MainActivity.java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:onClick="loadReact"
android:text="React Fragment"
android:id="@+id/react_native_loader"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/react_holder"/>
</LinearLayout>
What should I do? Am I using the Framelayout wrong or should I use a different component altogether?
I just want the React Native Stack Navigator Instance to work properly inside a Java app.