react-native添加片段以查看未显示

时间:2016-09-26 10:28:26

标签: android react-native

我已将动态生成的FrameLayout添加到react-native视图中。 Framelayout正在出现。但是当我向视图添加一个片段时,什么也没有显示。

这是代码的一部分:

    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);

因此Fragment存在问题。 任何想法为什么片段没有出现?

1 个答案:

答案 0 :(得分:5)

我也遇到了这个问题并找到了解决方案。

Android方面: 首先,创建一个layout_container.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) {
    mContext = context;
    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,与LinearLayout重复,以便您的应用不会崩溃。如果您将其他ID设置为容器视图,您将获得异常,应用程序将崩溃,因为无法从当前应用程序的布局中找到视图的ID。
您可以使用Android Studio中的Layout Inspector进行检查。

为防止重复ID,最好的方法是在xml中定义它们。 这就是为什么我从xml中提升根视图的原因 但是如果你为根设置了id(在我的例子中为didComponentMount()),那么当添加id时,RN将删除id,因此孩子是必要的。
在RN获得根视图(=INDEX($A$1:$E$27,MATCH(1,($A$1:$E$27=H1)*($A1:$E27=H2)*($A1:$E27=H3),0),5) )之后,您需要从RN组件调用create(),然后您就可以看到它。