hello I'm developing a react native app everything is fine but I have a problem
return (
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
<StatusBar
translucent={true}
backgroundColor={'rgba(0, 0, 0, 0.3)'}
barStyle={'light-content'}
/>
{ this.gradient }
<ScrollView
style={styles.scrollview}
scrollEventThrottle={200}
directionalLockEnabled={true}
>
{ carousel }
<FlatList
data={ this.state.GridListItems }
renderItem={ ({item}) =>
<TouchableOpacity
style={styles.GridViewContainer}
onPress={() => this.props.navigation.push('ProfileScreen', { height: "6'2", category: item.key })}>
<ImageBackground
source={{ uri: item.img }}
style={{width: '108%', height: '110%', justifyContent:'center'}}
>
<Text style={styles.GridViewTextLayout} > {item.key} </Text>
</ImageBackground>
</TouchableOpacity>
}
numColumns={2}
/>
</ScrollView>
</View>
</SafeAreaView>
);
styles
safeArea: {
flex: 1,
backgroundColor: colors.black
},
container: {
flex: 1,
backgroundColor: colors.background1
},
when I scroll down you see the mobile battery and wifi (top bar) is in the app
I want the app to be below the mobile topbar how can I achieve that?
here is an expo qr code
once try this and let me know your results:
import React,{Fragment} from 'react';
return (
<Fragment>
<SafeAreaView style={{ flex: 0, backgroundColor: 'red' }} />
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
{ this.gradient }
<ScrollView
style={styles.scrollview}
scrollEventThrottle={200}
directionalLockEnabled={true}
>
{ carousel }
<FlatList
data={ this.state.GridListItems }
renderItem={ ({item}) =>
<TouchableOpacity
style={styles.GridViewContainer}
onPress={() => this.props.navigation.push('ProfileScreen', { height: "6'2", category: item.key })}>
<ImageBackground
source={{ uri: item.img }}
style={{width: '108%', height: '110%', justifyContent:'center'}}
>
<Text style={styles.GridViewTextLayout} > {item.key} </Text>
</ImageBackground>
</TouchableOpacity>
}
numColumns={2}
/>
</ScrollView>
</View>
</SafeAreaView>
);
i added safeareaview (flex:0) for statusBar you can apply any color you want.
provide options in your navigator file as:
navigationName: {
screen: fileName,
navigationOptions: ({ navigation }) => {
if (Platform.OS === "android") {
return {
title: 'images',
headerStyle: {
backgroundColor: '#382464',
height: 50,
},
headerTitleStyle: {
color: '#fff',
},
headerTintColor: '#fff',
// header: props => <UriBar {...props} />
}
} else {
return {
header: null
}
}
}
},
you can also use statusBar for android
You should use SafeAreaView.
It will render your component without overlapping the "top bar".
import { SafeAreaView } from 'react-native'
...
return (
<SafeAreaView>
// your components
<SafeAreaView/>
)
Edit:
As you can see in the docs.
Simply wrap your top level view with a SafeAreaView with a flex: 1 style applied to it. You may also want to use a background color that matches your application's design.
So if you already using SafeAreaView, maybe you don't have flex: 1 and it's not working in the way you want.
Related
I have data in FlatList which is working fine.
The data is hidden by default but when I click on the arrow, I want it to appear below the field.
Problem is that, when I click on the icon, it appears without problem but items are not clickable on it.
But if I set that state data true by default, the clickable to list items works fine because it gets rendered on screen.
My requirements are as when this list appears with state change, the list should appear and be clickable without a problem. Currently, it does appear but when I try to click items, it disappears.
How we can do it? Because I also need to add a search on it later on. Please provide a long-term solution.
Code:
{getD ? (
<View style={{ flex: 1 }}>
<FlatList
style={{
flexGrow: 1,
flexShrink: 1,
flexDirection: 'column',
overflow: 'scroll',
maxHeight: 150,
position: 'absolute',
width: '100%',
zIndex: 10,
elevation: 10,
backgroundColor: '#ffffff',
borderRadius: 5,
borderWidth: 1,
borderStyle: 'solid',
borderColor: '#D7D7D7',
shadowOffset: { height: 3, width: 0 },
shadowRadius: 10,
shadowColor: '#00000010',
shadowOpacity: 1,
flex: 1,
}}
data={recSet}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => alert('xxxxx')}>
<View style={{}} />
<Text style={{}}>{item.title}</Text>
</TouchableOpacity>
)}
keyExtractor={(item) => item.id}
contentContainerStyle={{ flexGrow: 1 }}
extraData={getD}
/>
</View>
) : null}
I had no problem getting touches to register properly so I asssuming that you ended auto importing react-native-gesture-handler TouchableOpacity somewhere. Heres a demo:
/*create ToggleFlatlist component*/
import React, { useState } from 'react';
import { View, TouchableOpacity, FlatList, Text } from 'react-native';
export default function ToggableFlatList({
pressableStyle,
initialVisibility,
flatlistWrapperStyle,
onToggleChange,
...flatlistProps
}) {
const [isRendered, setIsRendered] = useState(initialVisibility);
const onToggle = () => {
const newValue = !isRendered;
setIsRendered(newValue);
onToggleChange?.(newValue);
};
return (
<TouchableOpacity
style={[{ flex: 1 }, pressableStyle]}
onPress={onToggle}>
{isRendered ? (
<View style={[{ flex: 1 }, flatlistWrapperStyle]}>
<FlatList {...flatlistProps} />
</View>
) : null}
</TouchableOpacity>
);
}
export default function App() {
const [isVisible, setIsVisible] = useState(false)
return (
<View style={styles.container}>
<Text style={styles.textInstructions}>Press anywhere to {isVisible ? 'hide':'reveal'} list</Text>
<ToggableFlatList
flatlistWrapperStyle={styles.flatlistWrapper}
initialVisibility={isVisible}
onToggleChange={setIsVisible}
style={styles.flatlist}
data={recSet}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => alert('xxxxx')}>
<View style={{}} />
<Text style={{}}>{item.title}</Text>
</TouchableOpacity>
)}
keyExtractor={(item) => item.id}
contentContainerStyle={{ flexGrow: 1 }}
/>
</View>
);
}
I am trying to show a modal without going to another screen, I want it to be displayed on the current screen but not through navigation. The modal doesn't pop up and I don't know the problem.
I am using the renderModal to show the modal on the screen.When I use this.props.navigation.navigate('AnotherModal'), it works but goes to another screen,this time I want to show modal on the same screen.
import * as React from 'react';
import { Text, View, Image,
StyleSheet,Alert,Modal,TouchableHighlight } from 'react-native';
import { Constants } from 'expo';
import { Appbar, Colors, FAB } from 'react-native-paper';
import ProductsModal from './ProductsModal';
import ModalTester from './ModalTester';
export default class AppBar extends React.Component {
state = {
modalVisible: false,
};
setModalVisible(visible)
{
this.setState({modalVisible: visible});
}
renderModal() {
return (
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
);
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.appbar}>
<Appbar style={styles.piece}>
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={this.renderModal.bind(this)}
/>
</Appbar>
<View>
<Image
source={require('../../assets/cutout.png')}
style={styles.cutout}
pointerEvents="none"
/>
<FAB
icon={require('../../assets/add_circle.png')}
color="#b2beb5"
onPress={() => navigate('Homes')}
style={styles.fab} />
</View>
<Appbar style={[styles.piece, styles.right]}>
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
//backgroundColor: '#ecf0f1',
padding: 8,
},
appbar: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 56,
flexDirection: 'row',
},
piece: {
flex: 1,
backgroundColor: Colors.grey300,
},
right: {
justifyContent: 'flex-end',
},
cutout: {
height: 56,
width: 80,
tintColor: Colors.grey300,
},
fab: {
position: 'absolute',
margin: 12,
bottom: 16
}
});
You should try to bind your setModalVisible in the constructor first:
constructor(props) {
super(props);
this. setModalVisible = this. setModalVisible.bind(this);
}
And then change your first Appbar.Action to something like this:
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={() => this. setModalVisible(true)}
/>
Also you have to add your Modal to the rendered code
...
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
{this.renderModal()}
</View>
I'm not sure the bind is necessary though
Since screen does not change, your Modal needs to be within the render method of that screen. This means it can be handled by the state of the component. For example to show it you can:
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={() => this.setModalVisible(true)}
/>
In the main render you can just add directly your renderModal, 'cause its visible prop is sufficient to handle the behavior:
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.appbar}>
<Appbar style={styles.piece}>
<Appbar.Action
icon={require('../../assets/devices.png')}
onPress={this.renderModal.bind(this)}
/>
</Appbar>
<View>
{this.renderModal()}
<Image
source={require('../../assets/cutout.png')}
style={styles.cutout}
pointerEvents="none"
/>
<FAB
icon={require('../../assets/add_circle.png')}
color="#b2beb5"
onPress={() => navigate('Homes')}
style={styles.fab} />
</View>
<Appbar style={[styles.piece, styles.right]}>
<Appbar.Action
icon={require('../../assets/account_box.png')}
onPress={() => console.log('Account pressed')}
/>
</Appbar>
</View>
);
}
I have issue that my swiper does not show images. Swiper and dots from swiper are there but images are not showing. I am pretty new to react-native. This is my code:
import React from 'react';
import {
StyleSheet,
View,
Image,
Text
} from 'react-native';
import Swiper from 'react-native-swiper';
export default class HomeScreen extends React.Component {
state = {
data: []
}
componentDidMount = () => {
this.setState({
data: this.props.navigation.getParam('data', 'NO-DATA')
});
}
render() {
return (
<View style={styles.container}>
<Swiper
style = {styles.swiper }
>
{
this.state.data.map( (item, i) => {
<View>
<Text> {item.url} </Text>
<Image
style={{width: 200, height: 200}}
source={{uri: item.url}}
/>
</View>
})
}
</Swiper>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center',
},
swiper: {
width: 200,
height: 200
}
});
The issue is not only with image, also it is happening with text, etc.
Am i missing something ?
Return is missing inside the map add it.
{
this.state.data.map && this.state.data.map( (item, i) => {
return(
<View>
<Text> {item.url} </Text>
<Image
style={{width: 200, height: 200}}
source={{uri: item.url}}
/>
</View>)
})
}
Or without return. If you use ( this bracket you no need to add return
{
this.state.data.map && this.state.data.map( (item, i) => (
<View>
<Text> {item.url} </Text>
<Image
style={{width: 200, height: 200}}
source={{uri: item.url}}
/>
</View>)
))
}
Here is the code for the camera. I want a button to open the camera. I don't want it to automatically open on app startup. Also is there any way to detect text in the image and save it?
import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Camera, Permissions } from 'expo';
export default class CameraExample extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
};
async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
}
You can put your view in a variable and render it on button press. In my camera I've done this for an image preview when the photo is taken:
if (BUTTON PRESS CONDITION) {
imageView = (
<View style={styles.previewContainer}>
<Image style={styles.imagePreview} source={{uri: `data:image/gif;base64,${base64Post}`}} />
<View style={styles.container}>
<TouchableOpacity style={styles.sendButton} onPress={() => Alert.alert("Not implemented!")}>
<Image style={{width: 70, height: 70}} source={require('../assets/Send.png')}/>
</TouchableOpacity>
</View>
<View style={styles.container} key={this.state.uniqueValue}>
<TouchableOpacity style={styles.undoButton} onPress={() => this.setState({ persist64: null})}>
<Image style={{width: 70, height: 70}} source={require('../assets/undoButton.png')}/>
</TouchableOpacity>
</View>
</View>
)
}
You could set up some boolean that when you press the button it is true renders the view of your camera. Then take the name of the view you made and put it somewhere in your render. like so:
{imageView}
If you need further explanation let me know.
Alternatively you could just create a separate page for your camera and have a button that navigates to the camera page.
You can simply connect the button and navigate to the camera on click. It is the very standard of navigating in both react or react native.. So just use whatever navigation library youre using, and use the nav props to redirect to camera onPress().
Anyone has experience of implementing react-native-modal?
While I'm using it, modal isn't closed when I tap outside of modal.
Here is what I've tried
Adding onBackdropPress(() => {this.props.hideModal()})
Adding TouchableWithoutFeedback inside and outside of components
and many other approaches...
Here is my the screen where I want to show my modal.
render() {
return (
<View style={{flex: 1}}>
<ScrollView>
// CONTENT HERE
{this._renderModal()} //rendering modal here
<FABs onFABsPress={this._showModal} /> // I open Modal when I press the FABs button
</ScrollView>
</View>
)
);
_renderModal = () => {
return (
<CameraImageSelectModal
hideModal={this._hideModal}
isModalVisible={this.state.isModalVisible}
navigation={this.props.navigation}
/>
)
}
Here is modal component : CameraImageSelectModal.js
render() {
let { isModalVisible } = this.props;
return (
<View>
<Modal
isVisible={isModalVisible}
onBackdropPress={() => {console.log('hey')}}>
transparent={true}>
<View style={styles.modalContainer}>
<View style={styles.modalTitleTextContainer}>
<Text style={styles.modalTitleText}>Hello World</Text>
</View>
<View style={styles.modalContentTextContainer}>
<Text style={styles.modalContentText}></Text>
</View>
<View style={styles.modalButtonContainer}>
<Button transparent onPress={this._handleCameraPress}>
<Text style={[styles.modalText, styles.black]}>Camera</Text>
</Button>
<Button transparent onPress={this._handleAlbumPress}>
<Text style={styles.modalText}>Album</Text>
</Button>
</View>
</View>
</Modal>
</View>
Thanks!!
I don't think the modal has that built in functionality, but you could create your own component that does. Here is a quick implementation. You might have to mess around with padding and margin to get it how you like, but this will allow the modal to be dismissed when pressing outside.
import React, { Component } from "react"
import { Modal, StyleSheet, View, TouchableHighlight } from "react-native"
const styles = StyleSheet.create({
container: {
zIndex: 1,
margin: 25,
backgroundColor: "white"
},
background: {
flex: 1
},
outerContainer: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: "center"
}
})
const MyModal = props => (
<Modal transparent={true} animationType={"slide"} visible={props.visible} onRequestClose={() => props.onRequestClose()}>
<TouchableHighlight style={styles.background} onPress={() => props.onRequestClose()} underlayColor={"transparent"}>
<View />
</TouchableHighlight>
<View style={ styles.outerContainer }>
<View style={styles.container}>
{props.children}
</View>
</View>
</Modal>
)
export { MyModal }
I just figured out why onBackdropPress = {() => console.log("Pressed")} didn't work..!!! onBackdropPress property was added since its version 3.xx and I was using 2.5.0 version.
So yarn update react-native-modal solved the issue.
If anyone encounters the problem that the library/component doesn't work as expected as you seen on documentation, try to check your package version number!
Cheers!
<Modal
isVisible={isModalVisible}
customBackdrop={
<View
style={styles.backDropContainer}
onTouchEnd={() => setModalVisible(false)}
/>
}
onBackdropPress={() => setModalVisible(false)}>
<View style={styles.modalContainer}>
<FlatList data={DATA} renderItem={() => <Text>hehehe</Text>} />
</View>
</Modal>
Style:
const styles = StyleSheet.create({
backDropContainer: {
flex: 1,
backgroundColor: 'black',
opacity: 0.5,
},
modalContainer: {
flex: 0.5,
backgroundColor: 'white',
padding: 10,
borderRadius: 10,
},
});