2016-09-26 153 views
1

我已经将一个动态生成的FrameLayout添加到反应原生视图。 Framelayout正在显示。但是当我向视图添加一个片段时,没有任何显示。react-native add fragment to view is not showing

这里是代码的一部分:

public FrameLayout createViewInstance(ThemedReactContext context) { 

      Fragment fragment = MapFragment.newInstance(mapKey); 
      FrameLayout view = new FrameLayout(context); 
      view.setWillNotDraw(false); 

      LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
      view.setLayoutParams(lp); 

      view.setId(View.generateViewId()); 

      view.setBackgroundColor(Color.parseColor("#1FFDDB")); 

      FragmentActivity activity = MainActivity.getFragmentActivity(); 

      FragmentManager fragmentManager = activity.getSupportFragmentManager(); 

      fragmentManager.beginTransaction().remove(fragment).commit(); 
      fragmentManager.executePendingTransactions(); 

      FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

      fragmentTransaction.add(0, fragment); 

      fragmentTransaction.show(fragment); 
      fragmentTransaction.attach(fragment); 
      fragmentTransaction.commit(); 
      fragmentManager.executePendingTransactions(); 
      return view; 
     } 

当我添加一个TextView到视图它显示:

// add a textfield to the view 
TextView textView1 = new TextView(context); 
textView1.setText("Android"); 
textView1.setTextSize(30); 
textView1.setGravity(Gravity.CENTER); 

view.setVisibility(View.VISIBLE); 

view.addView(textView1); 

所以与碎片的问题。 任何想法为什么片段不显示?

+0

http://stackoverflow.com/questions/34410559/how-do-we-get-an-android-fragment-to-show-up-in-react-native – Danieboy

+0

我已经实现它像解释在stackoverflow/34410559。但仍然没有显示出来。 –

+0

我替换了fragmentTransaction.add(0,fragment);与fragmentTransaction.add(view.getId(),fragment);但仍然是相同的问题(没有显示) –

回答

0

我也遇到过这个问题,找到了解决办法。

的Android侧: 首先,创建一个container_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:orientation="vertical"> 
    <FrameLayout 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</LinearLayout> 

然后它充气在createViewInstance方法和定义功能片段添加到容器中。

@Override 
public String getName() { 
    return "ExampleFragment"; 
} 
@Override 
protected View createViewInstance(ThemedReactContext reactContext) { 
    LinearLayout root = (LinearLayout) LayoutInflater.from(reactContext) 
       .inflate(R.layout.layout_container, null); 
    return root; 
} 

@Nullable 
@Override 
public Map<String, Integer> getCommandsMap() { 
    return MapBuilder.of(
      "create", COMMAND_CREATE 
    ); 

} 

@Override 
public void receiveCommand(View view, int commandId, @Nullable ReadableArray args) { 
    Log.d(TAG, "receiveCommand: " + commandId); 
    switch (commandId) { 
     case COMMAND_CREATE: 
      createFragment(); 
      break; 
    } 
} 

private void createFragment() { 
    MapFragment mapFragment = new MapFragment(); 
    mContext.getCurrentActivity() 
      .getFragmentManager() 
      .beginTransaction() 
      .add(R.id.container, mapFragment) 
      .commit(); 
} 

RN侧: 创建原生UI组件Fragment.js

import {NativeModules, requireNativeComponent, View, UIManager, findNodeHandle} from 'react-native'; 
const fragmentIFace = { 
    name: "Fragment", 
    propTypes: { 
    ...View.propTypes, 
    } 
}; 
const NativeFragment = requireNativeComponent("ExampleFragment", fragmentIFace); 
class ExampleFragment extends Component { 
    fragment; 
    render() { 
    return <NativeFragment 
     ref={c => this.fragment = c} 
     {...this.props} style={{flex: 1}}/> 
    } 

    create =() => { 
    UIManager.dispatchViewManagerCommand(
     findNodeHandle(this.fragment), 
     UIManager.MapFragment.Commands.create, 
     [] // No args 
    ) 
    } 
export default ExampleFragment 

那么您可以在RN使用它。

class App extends Component { 
    componentDidMount() { 
     this.fragment.create(); 
    } 
    render() { 
     return (
      <View> 
       <ExampleFragment ref={r=>this.fragment = r} /> 
      </View> 
     ); 
    } 
} 

这里的解释:
在你的代码,你尝试片段添加到不能是碎片容器的视图。
通常,View.generateViewId()将返回编号0x1,它与ReactRootView重复,以便您的应用程序不会崩溃。如果您将其他标识设置为容器视图,则会出现异常,并且应用会崩溃,因为无法从当前应用的布局中找到您的视图的标识。
您可以在Android Studio中使用Layout Inspector进行检查。

为了防止重复的ids,最好的方法是用xml来定义它们。 这就是为什么我膨胀从XML的根视图。
但是,如果你为根设置了id(在我的例子中为LinearLayout),那么当它被添加时,这个id将被RN删除,所以这个孩子是必须的。
RN获得根视图(didComponentMount())后,需要从RN组件调用create(),并且可以看到它。