react-native-barcode-builder icon indicating copy to clipboard operation
react-native-barcode-builder copied to clipboard

Barcode not display on Android

Open jason7toxic opened this issue 6 years ago • 9 comments

Anyone having this issue?

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

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

screenshot_1543159649

jason7toxic avatar Nov 25 '18 15:11 jason7toxic

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

inconspicuous-username avatar Jan 13 '19 15:01 inconspicuous-username

same problem here

lorenamelor avatar May 02 '19 16:05 lorenamelor

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

ntnamag avatar May 07 '19 04:05 ntnamag

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.

pouyaemami avatar Jun 03 '19 14:06 pouyaemami

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.

zausailov avatar Jun 13 '19 09:06 zausailov

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!

dickwyn avatar Aug 30 '19 17:08 dickwyn

Would someone be able to open a PR for this?

pouyaemami avatar Sep 12 '19 15:09 pouyaemami

Anyone found a solution for this?

SahanDll avatar Jul 16 '20 07:07 SahanDll

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 ( <View style={styles.container}> <Text>Current state is: {this.state.appState}</Text> </View> ); } }

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

export default AppStateExample;

SahanDll avatar Jul 16 '20 10:07 SahanDll