Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to get native Android view to show up in React Native

I'm trying to get a simple TextView to show up from Android's native code, onto my Javascript view. However, the application fails silently, and I only see the default "Hello World"

RCTScannerViewManager.java

public class RCTScannerViewManager extends SimpleViewManager<TextView> {

    public static final String REACT_CLASS = "RCTScannerView";

    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @Override
    protected TextView createViewInstance(ThemedReactContext reactContext) {
        TextView tv = new TextView(reactContext);
        tv.setText("hello from android !");
        return tv;
    }
}

RCTScannerViewPackage.java

public class RCTScannerViewPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager> asList(
                new RCTScannerViewManager()
        );
    }
}

MainApplication.java

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new RCTScannerViewPackage()
      );
    }
  };

ScannerView.js

import React, { Component } from 'react'
import { Text, View, requireNativeComponent } from 'react-native'

class ScannerView extends Component {
    render() {
        return <RCTScannerView />
    }
}

ScannerView.propTypes = {
    ...View.propTypes
}

const RCTScannerView = requireNativeComponent('RCTScannerView', ScannerView);

export default ScannerView

index.android.js

import React, { Component } from 'react'
import { AppRegistry, Text, View } from 'react-native';
import ScannerView from './ScannerView';

class AwesomeProject extends Component {
  render() {

    return (
        <View>
            <Text> Hello world </Text>
            <ScannerView></ScannerView>
        </View>
    );
  }
}

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject)
like image 866
Carpetfizz Avatar asked Apr 17 '17 16:04

Carpetfizz


1 Answers

I suspect that this has to do something with you forgetting to add the layouting attributes for your components.

To my understanding, React Native does layouting exclusively via it's custom Flexbox layout engine (currently Yoga). So if you don't specify any flexbox attributes, it will either not attach any native views, or attach them with 0 width/height/x/y.

This article helped me a lot, and the attached repo with a working solution.

To be even more specific, I think something along the lines of this should do the trick:

import React, { Component } from 'react'
import { AppRegistry, Text, View } from 'react-native';
import ScannerView from './ScannerView';

class AwesomeProject extends Component {
  render() {

    return (
        <View style={styles.container}>
            <Text style={styles.hello}> Hello world </Text>
            <ScannerView style={styles.scannerview}></ScannerView>
        </View>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10
  },
  scannerview: {
    height: 100,
    width: 100,
  },
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject)
like image 170
Zsombor Erdődy-Nagy Avatar answered Oct 12 '22 18:10

Zsombor Erdődy-Nagy