Search code examples
react-nativestyles

improving elements styles to make a full screen scan


I will need a helping hand to edit this page. i have all the elements but i need help styling. I would like to have the camera (the image you see is the typical emulator camera, that's why it makes an image) in full screen and from above at the top, the message in red and the 'autocomplete. If you want, to explain better, I would like to respect the image below: autocomplete at the top left above the camera in full screen.

would it be possible for you to help me, I'm getting a little confused. I tried to do a snack but failed. I will add it later if i can.

enter image description here

const autocompletes = [...Array(10).keys()];

const apiUrl = "https://5b927fd14c818e001456e967.mockapi.io/branches";


class Tickets extends Component {
  constructor(props) {
    super(props);
    this.state = {
      Press: false,
      hasCameraPermission: null,
      reference: '',
      lastScannedUrl:null,
      displayArray: []      
    };
  }

   initListData = async () => {
    let list = await getProductByRef(1);
   
    if (list) {
      this.setState({
        displayArray: list,
        reference: list.reference
      });      
    }
   // console.log('reference dans initListData =', list.reference)
  };

  async UNSAFE_componentWillMount() {
    this.initListData();
   // console.log('reference dans le state =', this.state.reference)

};

  componentDidMount() {
    this.getPermissionsAsync(); 
  }

  getPermissionsAsync = async () => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA);
    this.setState({ hasCameraPermission: status === "granted" });
  };

  _onPress_Scan = () => {
    this.setState({
      Press: true
    });
  }

  handleBarCodeScanned = ({ type, data }) => {
    this.setState({ Press: false, scanned: true, reference: data });
    this.props.navigation.navigate('ProductDetails', {reference : parseInt(this.state.state.reference)})
  };

  renderBarcodeReader = () => {
    const { hasCameraPermission, scanned } = this.state;

    if (hasCameraPermission === null) {
      return <Text>{i18n.t("scan.request")}</Text>;
    }
    if (hasCameraPermission === false) {
      return <Text>{i18n.t("scan.noaccess")}</Text>;
    }
    return (
      <View
        style={{
          flex: 1,
          ...StyleSheet.absoluteFillObject
        }}
      >        
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
          style={{ flex:1, height:'100%', ...StyleSheet.absoluteFillObject}}
        />
        {scanned && (
          <Button
            title={"Tap to Scan Again"}
            onPress={() => this.setState({ scanned: false })}
          />
        )}    
      </View>
    );
  }
  handleSelectItem(item, index) {
    const {onDropdownClose} = this.props;
    onDropdownClose();
    console.log(item);
  }
  render() {
    const { hasCameraPermission, scanned, Press } = this.state;
    let marker = null;

    const {scrollToInput, onDropdownClose, onDropdownShow} = this.props;

 // console.log('displayArray', this.state.displayArray, 'reference', this.state.displayArray.reference)
    return (
           <View style={styles.container}>           
    {Press ? (
      <View style={{flex:1}}>
        <View style={styles.dropdownContainerStyle}>            
          <Autocomplete
            key={shortid.generate()}
            containerStyle={styles.autocompleteContainer}
            inputStyle={{ borderWidth: 1, borderColor: '#F78400'}}
            placeholder={i18n.t("tickets.warning")}
            pickerStyle={styles.autocompletePicker}
            scrollStyle={styles.autocompleteScroll}
            scrollToInput={ev => scrollToInput(ev)}
            handleSelectItem={(item, id) => this.handleSelectItem(item, id)}
            onDropdownClose={() => onDropdownClose()}
            onDropdownShow={() => onDropdownShow()}              
            fetchDataUrl={apiUrl}
            minimumCharactersCount={2}
            highlightText
            valueExtractor={item => item.name}
            rightContent
            rightTextExtractor={item => item.properties}
          />
        </View>
        {this.renderBarcodeReader()}
      </View>
    ) : (
      <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
        <Button
          color="#F78400"
          title={i18n.t("scan.scan")}
          onPress={this._onPress_Scan}>                    
        </Button>
      </View>
    )}                
  </View>
    );
  }
}
export default Tickets;

This gives me (after pressing the button) :

SNACK CODE TEST

screencapture


Solution

  • I notice You are using a component from Expo called BarCodeScanner

    There's a github issue open about the fact that this component is not possible to be styled for full screen: https://github.com/expo/expo/issues/5212

    However one user proposes a good solution: replace BarCodeScanner with Camera and use barcodescannersettings

    Here's a link for the answer on the gitHub issue: https://github.com/expo/expo/issues/5212#issuecomment-653478266

    Your code should look something like:

    renderBarcodeReader = () => {
        const { hasCameraPermission, scanned } = this.state;
    
        [ ... ] // the rest of your code here
    
        return (
          <View
            style={{
            flex: 1,
            ...StyleSheet.absoluteFillObject
          }}
         >        
          <Camera
            onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
            style={{ flex:1}}
            barCodeScannerSettings={{
              barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
            }}
          />
        </View>
      );
    }