2016-08-05 6 views
3

Ich habe bereits eine Android-Anwendung, die ich gerne in Native React verwenden würde. Es ist eine große Anwendung, und ich möchte nicht alles auf einmal migrieren. Zum Beispiel ist mein Symbolleisten-Code ein bisschen komplex und ich möchte ihn jetzt nativ belassen. Also mein Layout sieht ungefähr so ​​aus:Kann ein ReactRootView verschachtelt werden (Android)

<RelativeLayout 
    android:id="@+id/relative_layout" 
    android:background="@color/background_color" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/action_bar" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true"/> 

    <com.facebook.react.ReactRootView 
     android:id="@+id/react_root" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</RelativeLayout> 

Und in onCreate(), anstatt eine neue ReactRootView schaffen ich das tue:

mReactRootView = (ReactRootView) findViewById(R.id.react_root); 
... // Other init 
setContentView(mReactRootView); 

Aber ich bin immer einen Fehler auf setContentView (mReactRootView):

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 

Dies führt mich ich nicht verschachtelt ein Wurzel Blick in andere Ansichten Reagieren glauben kann. Wie würde ich meine aktuelle Toolbar-Implementierung behalten, aber für den Rest der Seite immer noch React Native verwenden? Ich weiß, dass das existiert: https://facebook.github.io/react-native/docs/native-components-android.html Ist Bridging mit der nativen Komponente meine einzige Option?

bearbeiten: Konstantin Vorschlag unten und hier folgt, was ich habe:

ReactFragment.java

public class ReactFragment extends Fragment implements DefaultHardwareBackBtnHandler { 
    ViewGroup group = (ViewGroup) inflater.inflate(R.layout.react_fragment, container, false); 
    activity = getActivity(); 

    mReactRootView = new ReactRootView(activity); 
    mReactInstanceManager = ReactInstanceManager.builder() 
      .setApplication(activity.getApplication()) 
      .setBundleAssetName("index.bundle") 
      .setJSMainModuleName("index") 
      .addPackage(new MainReactPackage()) 
      .setUseDeveloperSupport(true) 
      .setInitialLifecycleState(LifecycleState.RESUMED) 
      .build(); 

    group.addView(mReactRootView); 
    mReactRootView.startReactApplication(mReactInstanceManager, "AwesomeProject", null); 
    mReactInstanceManager.onHostResume(activity, this); 
    return group; 
} 
// onPause() onDestroy() etc. 

react_fragment.xml

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/react_root" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
</FrameLayout> 

Added

main_content.xml
... 
<fragment 
    android:name="com.amazon.kindlestore.main.ReactFragment" 
    android:id="@+id/react_frag" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 
... 

Und ich hinzufüge, das Fragment wie dies in meiner Haupttätigkeit:

ReactFragment reactFragment = (ReactFragment) getFragmentManager().findFragmentById(R.id.react_frag); 
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 
fragmentTransaction.add(R.id.react_frag, reactFragment); 
fragmentTransaction.commit(); 

Dies scheint zu funktionieren, ich habe meine Komponenten reagieren unter meiner Mutter Toolbar Rendering

+0

ich habe gleiches Problem in meiner Anwendung. Ich muss benutzerdefinierte Registerkarte verwenden, die ich Android native Anwendung verwenden. aber jetzt ist ein Teil meiner App reagiert native ist es gibt eine Möglichkeit, nur zeigen/ausblenden Tab bar in reagieren nativ mit reaktion nativen Brücke –

Antwort

0

Sie haben ein Fragment erstellen für RN ui Teil und verwenden Sie es in Ihrem XML-Layout. In diesem Fragment erstellen Sie ReactRootView, dann erstellen oder erhalten Sie ReactInstanceManager, die Sie in den Lifecycle-Callbacks von Fragment einhängen müssen. Und dann starten Sie Ihre RN-Anwendung innerhalb der ReactRootView mit diesem Instanz-Manager.

Schauen Sie sich dieses offiziellen guide (vergessen Sie nicht, Android in Top-Menü wählen)

+0

Ich versuchte dies und machte einige Fortschritte, aber die Dinge funktionieren immer noch nicht. Kannst du dir den Schnitt anschauen, den ich zu der Frage gemacht habe, und sehen, ob mir irgendetwas fehlt? – Chris

+0

Ich habe bemerkt, dass Sie BundleAssetName, JSMainModuleName geändert haben. Sind Sie sicher, dass Ihr js-Bundle unter diesen Namen verfügbar ist? Stellen Sie js bundle asset zur Verfügung, wenn Sie Ihre App packen oder bedienen Sie sie vom Entwicklungsknotenserver? Und verwenden Sie den korrekten Namen der reaktiven Komponente, dh registrieren Sie ihn in Ihrem js-Code wie 'AppRegistry.registerComponent ('AwesomeProject', ...'? –

+0

) Nachdem ich dieses Update gepostet hatte, erkannte ich, dass ich versuchte, mein ReactRootView in ein anderes ReactRootView zu verschachteln Ich habe react_fragment.xml geändert, um ein FrameLayout anstelle von einem ReactRootView zu enthalten und die Dinge scheinen gut zu funktionieren. Danke! – Chris

Verwandte Themen