October 22, 2024
Chicago 12, Melborne City, USA
Android

React Native Expo – Button disappear when tested on APK build


I’m facing critical differences between the development version and the build version of my React Native app only on Android using Expo. The main issues I’m encountering is that the close button visible in the development version is missing in the build version (and other smaller UI problems)

Here are the 2 screens:

Development Version (Expo Go)

enter image description here

Build version

enter image description here

Here is the relevant code that handles the double-tap gesture and the UI rendering:

import React, { useState, useEffect, useRef, useCallback } from 'react';
import { StyleSheet, Text, View, Dimensions, Image, TouchableWithoutFeedback, TouchableOpacity } from 'react-native';
// libraries
import { CameraView, useCameraPermissions } from 'expo-camera';
import { Button, Divider, IconButton } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialIcons';
// components
import CustomDashedLine from '../components/CustomDashline';

// ----------------------------------------------------------------------

const { height: DEVICE_HEIGHT, width: DEVICE_WIDTH } = Dimensions.get('window');

// ----------------------------------------------------------------------

const CameraScreen = ({ navigation, route }) => {
 
  const [isTakingPicture, setIsTakingPicture] = useState(false);
  const [showPrompt, setShowPrompt] = useState(true);
  const tapRef = useRef(null);

  const handleDoubleTap = useCallback(() => {
    if (tapRef.current !== null) {
      clearTimeout(tapRef.current);
      setShowPrompt(false);
      tapRef.current = null;
    } else {
      tapRef.current = setTimeout(() => {
        tapRef.current = null;
      }, 200);
    }
  }, []);

  useEffect(() => {
    setShowPrompt(true);
  }, [step]);

  const takePicture = async () => {
    // take the pic and send with API
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity 
        style={{ flex: 1, zIndex: 1 }}
        onPress={!showPrompt ? takePicture : null} 
        disabled={isTakingPicture}
        activeOpacity={1}
      >
        <CameraView
          style={styles.camera}
          type="back"
          ref={(ref) => {camera = ref}}
        >
          <View style={styles.buttonContainer}>
            <IconButton // <--- This button here
              icon={() => <Icon name="close" size={30} color="white" />}
              size={40}
              onPress={() => {
                navigation.goBack();
                setEnableTorch(false)
              }}
              style={styles.iconButton}
            />
          </View>
          {showPrompt && (
            <TouchableWithoutFeedback onPress={handleDoubleTap}>
              <View style={styles.fullScreenTouchable}>
                <View style={styles.promptContainer}>
                  <Text style={styles.promptText}>A Text here</Text>
                  <Image source={imageUrl} />
                </View>
              </View>
            </TouchableWithoutFeedback>
          )}
          {!showPrompt && (
            <View style={styles.overlay}>
              <CustomDashedLine style={styles.cropLine}/>
              <CustomDashedLine style={styles.cropLine}/>
            </View>
          )}
        </CameraView>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  camera: {
    flex: 1,
    width: '100%',
    height: '100%',
  },
  buttonContainer: {
    position: 'absolute',
    right: 20,
    bottom: 20,
    alignSelf: 'center',
    alignItems: 'center',
    zIndex: 10,
    backgroundColor: 'transparent',
  },
  iconButton: {
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
    borderRadius: 50,
  },
  text: {
    fontSize: 24,
    fontWeight: 'bold',
    color: 'white',
  },
  divider: {
    backgroundColor: 'white',
    width: 2,
    height: 200,
    marginVertical: 25,
    opacity: 0.5,
  },
  fullScreenTouchable: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
  },
  promptContainer: {
    backgroundColor: 'rgba(0, 0, 0, 0.7)',
    padding: 20,
    borderRadius: 10,
    transform: [{ rotate: '90deg' }],
  },
  promptText: {
    color: 'white',
    fontSize: 18,
    textAlign: 'center',
    transform: [{ scaleX: -1 }]
  },
  overlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
  cropLine: {
    position: 'absolute',
    left: '20%',
    width: '70%',
  },
});


export default CameraScreen;



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video