wonsikin / react-native-barcode-builder

Component for generating barcode in react native app
Other
176 stars 117 forks source link

Barcode not display on Android #35

Open jason7toxic opened 6 years ago

jason7toxic commented 6 years ago

Anyone having this issue?

import Barcode from "react-native-barcode-builder";

<Barcode value="1OpzLsiooEe3ac786JY2nQ==" text="1OpzLsiooEe3ac786JY2nQ==" format="CODE128" width={1} height={100} />

screenshot_1543159649

inconspicuous-username commented 5 years ago

I have the same issue on my android devices (Nexus 7, Xiaomi mi5s plus, and oneplus 5) using Expo. It occurs even when I copy all the source files from the included example in an new Expo project. It might be some Expo related issue as the examples aren't an expo project, but I'm not proficient enough to try it out (First time ever using react-native).

lorenamelor commented 5 years ago

same problem here

ntnamag commented 5 years ago

I copy and edit using Svg. You can preview my code. Hope can help you

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

import barcodes from 'jsbarcode/src/barcodes';
import {Path, Svg} from 'react-native-svg';

export default class BarCode extends Component {
    static defaultProps = {
        value: undefined,
        format: 'CODE128',
        text: undefined,
        width: 2,
        height: 100,
        lineColor: '#000000',
        textColor: '#000000',
        background: '#ffffff',
        onError: undefined
    };

    constructor(props) {
        super(props);
        this.state = {
            bars: [],
            barCodeWidth: 0
        };
    }

    componentDidMount() {
        this.update();
    }

    componentDidUpdate() {
        this.update();
    }

    update() {
        const encoder = barcodes[this.props.format];
        const encoded = this.encode(this.props.value, encoder, this.props);

        if (encoded) {
            this.state.bars = this.drawSvgBarCode(encoded, this.props);
            this.state.barCodeWidth = encoded.data.length * this.props.width;
        }
    }

    drawSvgBarCode(encoding, options = {}) {
        const rects = [];
        // binary data of barcode
        const binary = encoding.data;

        let barWidth = 0;
        let x = 0;
        let yFrom = 0;
        // alert(JSON.stringify(options));

        for (let b = 0; b < binary.length; b++) {
            x = b * options.width;
            if (binary[b] === '1') {
                barWidth++;
            } else if (barWidth > 0) {
                rects[rects.length] = this.drawRect(
                    x - options.width * barWidth,
                    yFrom,
                    options.width * barWidth,
                    options.height
                );
                barWidth = 0;
            }
        }

        // Last draw is needed since the barcode ends with 1
        if (barWidth > 0) {
            rects[rects.length] = this.drawRect(
                x - options.width * (barWidth - 1),
                yFrom,
                options.width * barWidth,
                options.height
            );
        }

        return rects;
    }

    drawRect(x, y, width, height) {
        return `M${x},${y}h${width}v${height}h-${width}z`;
    }

    getTotalWidthOfEncodings(encodings) {
        let totalWidth = 0;
        for (let i = 0; i < encodings.length; i++) {
            totalWidth += encodings[i].width;
        }
        return totalWidth;
    }

    // encode() handles the Encoder call and builds the binary string to be rendered
    encode(text, Encoder, options) {
        // Ensure that text is a string
        text = '' + text;

        var encoder;

        try {
            encoder = new Encoder(text, options);
        } catch (error) {
            // If the encoder could not be instantiated, throw error.
            if (this.props.onError) {
                this.props.onError(new Error('Invalid barcode format.'));
                return;
            } else {
                throw new Error('Invalid barcode format.');
            }
        }

        // If the input is not valid for the encoder, throw error.
        if (!encoder.valid()) {
            if (this.props.onError) {
                this.props.onError(new Error('Invalid barcode for selected format.'));
                return;
            } else {
                throw new Error('Invalid barcode for selected format.');
            }
        }

        // Make a request for the binary data (and other infromation) that should be rendered
        // encoded stucture is {
        //  text: 'xxxxx',
        //  data: '110100100001....'
        // }
        var encoded = encoder.encode();

        return encoded;
    }

    render() {
        this.update();
        const backgroundStyle = {
            backgroundColor: this.props.background
        };
        return (
            <View style={[styles.svgContainer, backgroundStyle]}>
                <Svg height={this.props.height} width={this.state.barCodeWidth}>
                    <Path d={this.state.bars.join(",")} stroke={this.props.lineColor}/>
                </Svg>
                {typeof (this.props.text) != 'undefined' &&
                <Text style={{
                    color: this.props.textColor,
                    width: this.state.barCodeWidth,
                    textAlign: 'center'
                }}>{this.props.text}</Text>
                }
            </View>
        );
    }
}

const styles = StyleSheet.create({
    svgContainer: {
        alignItems: 'center',
        padding: 10
    }
});
pouyaemami commented 5 years ago

This issue happens for me on Android when I render the barcode off-screen and then bring it into view. It doesn't happen when I render the barcode on-screen on mount.

zausailov commented 5 years ago

I copy and edit using Svg. You can preview my code. Hope can help you

<Svg height={this.props.height} width={this.state.barCodeWidth}>
       <Path d={this.state.bars.join(",")} stroke={this.props.lineColor}/>
</Svg>
});

Works for me. Thx very much.

dickwyn commented 5 years ago

Ran into an issue with @ntnamag's code. Modified the following lines and it worked.

<Svg height={this.props.height} width={this.state.barCodeWidth}>
   <Path d={this.state.bars.join(' ')} stroke={this.props.lineColor} />
</Svg>

Thanks!

pouyaemami commented 5 years ago

Would someone be able to open a PR for this?

SahanDll commented 4 years ago

Anyone found a solution for this?

SahanDll commented 4 years ago

Use below code to identify the foreground event and refresh your data.

import React, { Component } from "react"; import { AppState, StyleSheet, Text, View } from "react-native";

class AppStateExample extends Component { state = { appState: AppState.currentState };

componentDidMount() { AppState.addEventListener("change", this._handleAppStateChange); }

componentWillUnmount() { AppState.removeEventListener("change", this._handleAppStateChange); }

_handleAppStateChange = nextAppState => { if ( this.state.appState.match(/inactive|background/) && nextAppState === "active" ) { console.log("App has come to the foreground!"); } this.setState({ appState: nextAppState }); };

render() { return (

Current state is: {this.state.appState}
);

} }

const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center" } });

export default AppStateExample;