React Native TouchableOpacity full width style not working - react-native

I am trying to put a simple Username-Password-Login button layout in react-native.
Problem I found is with style on TouchableOpacity button area. I have put width as 80% but still button width is showing only what text "LOGIN" requires. I want that button area to be of full width or 80%.
const Practice27 = (props) => {
const [text, setText] = useState("");
const [textp, setTextp] = useState("");
return (
<View style={styles.container}>
<View style={styles.inputView}>
<TextInput
placeholder="Username..."
value={text}
keyboardType="email-address"
style={styles.inputText}
onChangeText={(text) => {
setText(text);
username = text;
}}
></TextInput>
</View>
<View style={styles.inputView}>
<TextInput
placeholder="Password..."
style={styles.inputText}
secureTextEntry={true}
value={textp}
onChangeText={(textp) => {
setTextp(textp);
password = textp;
}}
></TextInput>
</View>
<TouchableOpacity style={styles.loginBtn} onPress={login}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#003f5c",
alignItems: "center",
justifyContent: "center",
},
loginBtn: {
backgroundColor: "#33eacd",
height: 50,
justifyContent: "center",
alignItems: "center",
padding: 10,
borderRadius: 25,
width: "80%",
},
loginText: {
color: "white",
},
inputView: {
width: "80%",
backgroundColor: "#465881",
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: "center",
padding: 20,
},
inputText: {
height: 50,
color: "white",
},
});
export default Practice27;

const Practice27 = (props) => {
const [text, setText] = useState("");
const [textp, setTextp] = useState("");
return (
<View style={styles.container}>
<View style={styles.inputView}>
<TextInput
placeholder="Username..."
value={text}
keyboardType="email-address"
style={styles.inputText}
onChangeText={(text) => {
setText(text);
username = text;
}}
></TextInput>
</View>
<View style={styles.inputView}>
<TextInput
placeholder="Password..."
style={styles.inputText}
secureTextEntry={true}
value={textp}
onChangeText={(textp) => {
setTextp(textp);
password = textp;
}}
></TextInput>
</View>
<View style={styles.loginBtn}> //using a view tag here
<TouchableOpacity onPress={login}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#003f5c",
alignItems: "center",
justifyContent: "center",
},
loginBtn: {
backgroundColor: "#33eacd",
height: 50,
justifyContent: "center",//you using alignitem center Thats why i remove this
padding: 10,
borderRadius: 25,
width: "80%",
},
loginText: {
color: "white",
},
inputView: {
width: "80%",
backgroundColor: "#465881",
borderRadius: 25,
height: 50,
marginBottom: 20,
padding: 20,
},
inputText: {
height: 50,
justifyContent: "center",
textAlign:"center"
color: "white",
},
});
export default Practice27;
Just copy and Pest it...This will works for you...I am Giving Comments where I changed...

You can use dimensions for give width, height, margins, padding etc. When you use dimension it work different screen sizes without no problem.
import { Dimensions } from 'react-native';
const window = Dimensions.get('window');
const Practice27 = (props) => {
const [text, setText] = useState("");
const [textp, setTextp] = useState("");
return (
<View style={styles.container}>
<View style={styles.inputView}>
<TextInput
placeholder="Username..."
value={text}
keyboardType="email-address"
style={styles.inputText}
onChangeText={(text) => {
setText(text);
username = text;
}}
></TextInput>
</View>
<View style={styles.inputView}>
<TextInput
placeholder="Password..."
style={styles.inputText}
secureTextEntry={true}
value={textp}
onChangeText={(textp) => {
setTextp(textp);
password = textp;
}}
></TextInput>
</View>
<TouchableOpacity style={styles.loginBtn} onPress={login}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#003f5c",
alignItems: "center",
justifyContent: "center",
},
loginBtn: {
backgroundColor: "#33eacd",
height: 50,
justifyContent: "center",
alignItems: "center",
padding: 10,
borderRadius: 25,
width: (window.width)*0.9,//this means button get width window-width*0.9
},
loginText: {
color: "white",
},
inputView: {
width: "80%",
backgroundColor: "#465881",
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: "center",
padding: 20,
},
inputText: {
height: 50,
color: "white",
},
});
export default Practice27;

Related

Can I put text outside ImageBackground in a ScrollView?

I am trying to have the text scroll with the image, like in this example:
https://reactnative.dev/docs/animations#scrollview-with-animated-event-example. But I want the text to be below of the image.
When I try to push the text outside with a margin or padding, the text disappears, and when I convert the image to have overflow visible, it still doesn't work(and I don't want to be able to drag the image to move around up/down.)
Here is the main code:
const images = new Array(6).fill('https://images.unsplash.com/photo-1556740749-887f6717d7e4');
const App = () => {
const scrollX = useRef(new Animated.Value(0)).current;
const { width: windowWidth } = useWindowDimensions();
return (
<SafeAreaView style={styles.container}>
<View style={styles.scrollContainer}>
<ScrollView
horizontal={true}
pagingEnabled
showsHorizontalScrollIndicator={false}
onScroll={Animated.event([
{
nativeEvent: {
contentOffset: {
x: scrollX
}
}
}
])}
scrollEventThrottle={1}
>
{images.map((image, imageIndex) => {
return (
<View
style={{ width: windowWidth, height: 250 }}
key={imageIndex}
>
<ImageBackground source={{ uri: image }} style={styles.card}>
<View style={styles.textContainer}>
<Text style={styles.infoText}>
{"Image - " + imageIndex}
</Text>
</View>
</ImageBackground>
</View>
);
})}
</ScrollView>
<View style={styles.indicatorContainer}>
{images.map((image, imageIndex) => {
const width = scrollX.interpolate({
inputRange: [
windowWidth * (imageIndex - 1),
windowWidth * imageIndex,
windowWidth * (imageIndex + 1)
],
outputRange: [8, 16, 8],
extrapolate: "clamp"
});
return (
<Animated.View
key={imageIndex}
style={[styles.normalDot, { width }]}
/>
);
})}
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
scrollContainer: {
height: 300,
alignItems: "center",
justifyContent: "center"
},
card: {
flex: 1,
marginVertical: 4,
marginHorizontal: 16,
borderRadius: 5,
overflow: "hidden",
alignItems: "center",
justifyContent: "center"
},
textContainer: {
backgroundColor: "rgba(0,0,0, 0.7)",
paddingHorizontal: 24,
paddingVertical: 8,
borderRadius: 5
},
infoText: {
color: "white",
fontSize: 16,
fontWeight: "bold"
},
normalDot: {
height: 8,
width: 8,
borderRadius: 4,
backgroundColor: "silver",
marginHorizontal: 4
},
indicatorContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
}
});
Any help would be appreciated (:

How to show different tags, depending on the user logged. Expo react

I need to show different tags depending on which user is logged.
Franchisee will see: 'Central' 'Empleados' 'Clientes'.
Employee: 'Store' 'Clientes'
User: none. just the generic info.
Here is my code:
(this is the array that states the scrollview)
const Chats = (props) => {
const TAGS = [
"store",
"Clientes",
"Central",
"Empleados",
]
and this is the component:
import React, { useState } from "react";
import { StyleSheet, FlatList, TouchableOpacity, ScrollView, Image } from 'react-native';
import { SimpleHeader, View, Text } from '../../elements/index';
const Chatstores = ({ chatsstore, navigation }) => (
<View>
<TouchableOpacity onPress={() => navigation.navigate("ChatPersonal")}>
<View style={styles.list} >
<Image source={chatsstore.img} style={styles.iconimg} />
<View style={styles.dataText}>
<View style={styles.nametime}>
<Text style={styles.text}>{chatsstore.name} </Text>
<Text >{chatsstore.time}</Text>
</View>
<Text style={styles.msg}>{chatsstore.msg} </Text>
</View>
</View>
</TouchableOpacity>
</View>
);
const ChatClients = ({ chatsClients, navigation }) => (
<View>
<TouchableOpacity onPress={() => navigation.navigate("ChatPersonal")}>
<View style={styles.list}>
<Image source={chatsClients.img} style={styles.iconimg} />
<View style={styles.dataText}>
<View style={styles.nametime}>
<Text style={styles.text}>{chatsClients.name} </Text>
<Text >{chatsClients.time}</Text>
</View>
<Text style={styles.msg}>{chatsClients.msg} </Text>
</View>
</View>
</TouchableOpacity>
</View>
);
const Chats = (props) => {
const { TAGS, chatsstore, chatsClients, navigation } = props;
const [selectedTag, setSelectedTag] = useState(null)
const [routeDistance, setRouteDistance] = useState(0);
return (
<View style={styles.wrapper}>
<SimpleHeader
style={styles.head}
titleLeft="Chats"
onSearchPress
onAddPress
/>
{/**shows horizontal, scrollview of Tags. */}
<View style={styles.scrollview}>
<ScrollView horizontal showsHorizontalScrollIndicator={false} >
<View style={styles.viewcontainer}>
{TAGS.map((tag) => (
<TouchableOpacity
onPress={() =>
setSelectedTag(tag === selectedTag ? null : tag)
}>
<View
style={[
styles.tag,
selectedTag === tag ? styles.selectedTag : {}
]}>
<Text style={styles.textTag}>{tag}</Text>
</View>
</TouchableOpacity>
))}
</View>
</ScrollView>
</View>
{/**If tag is store, shows its data, otherwise the rest */}
{selectedTag === "store" ? (
<View style={styles.chat}>
<FlatList
data={chatsstore}
renderItem={({ item, index }) => (
<Chatstores
chatsstore={item}
index={index}
navigation={navigation}
/>
)}
keyExtractor={(chatsstore) => chatsstore.name}
ListEmptyComponent={() => (
<Text center bold>No hay ningĂșn mensaje de clientes</Text>
)}
/>
</View>
) :
<View style={styles.chat}>
<FlatList
data={chatsClients}
renderItem={({ item, index }) => (
<ChatClients
chatsClients={item}
index={index}
navigation={navigation}
/>
)}
keyExtractor={(chatsClients) => chatsClients.name}
ListEmptyComponent={() => (
<Text center bold>No hay ningĂșn mensaje de clientes</Text>
)}
/>
</View>
}
</View>
);
};
const styles = StyleSheet.create({
wrapper: {
backgroundColor: "#ffffff",
display: "flex",
flex: 1,
},
head: {
height: 80,
display: "flex",
alignItems: "center",
zIndex: 1,
top: 5,
},
scrollview: {
display: "flex",
alignItems: "center",
justifyContent: "space-evenly",
},
viewcontainer: {
display: "flex",
flexDirection: "row",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 1,
right: 10,
},
list: {
bottom: 15,
flexWrap: "wrap",
alignContent: "space-between",
position: "relative",
marginVertical: 2,
backgroundColor: "#fff",
shadowColor: "#000",
elevation: 2,
flexDirection: "row",
}, dataText: {
alignSelf: "center",
flexDirection: "column",
width: "80%",
},
nametime: {
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
},
iconimg: {
display: "flex",
height: 43,
width: 43,
alignSelf: "center",
flexDirection: "column",
},
chat: {
margin: 10,
},
text: {
margin: 10,
fontFamily: "Montserrat_700Bold",
paddingHorizontal: 10,
},
msg: {
margin: 10,
fontFamily: "Montserrat_400Regular",
fontSize: 15,
paddingHorizontal: 10,
bottom: 10
},
map: {
display: "flex",
height: "100%",
},
tag: {
display: "flex",
alignSelf: "center",
marginBottom: 1,
width: 225,
padding: 10,
},
selectedTag: {
borderBottomColor: '#F5BF0D',
borderBottomWidth: 2,
},
textTag: {
fontFamily: "Montserrat_700Bold",
alignItems: "center",
textAlign: "center",
fontSize: 15,
},
buttonContainer: {
marginHorizontal: 20
},
button: {
backgroundColor: "#000000",
top: Platform.OS === 'ios' ? 12 : 20,
height: 60,
marginBottom: 40,
marginRight: 10,
},
});
export default Chats;
So I guess that in my "show horizontal tags" I should write some kind of if, that gets the role from the user token?
Or would it be better to write different routes into the navigation and handle it in 3 different components?

FlatList react native not scrolling

I have made sure that the parent Views contain flex:1, and I have wrapped the FlatList in a view with Flex 1 but nothing I seem to try enables my flat list to scroll.
I have gone through previous posts and none of the solutions have worked
Any help or suggestions would be greatly appreciated.
This is my code in order from parent to children
const App = () => {
return (
<View style={styles.container}>
<AuthProvider>
<Home />
</AuthProvider>
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1},
});
export default App;
const Home = () => {
const [userAuth] = useContext(AuthContext);
//{userAuth.auth && <Header title={'Stokebook'} />}
return (
<View style={styles.container}>
{userAuth.auth && <Profile />}
{!userAuth.auth && <LoginHome />}
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1},
});
const Profile = () => {
const [userAuth] = useContext(AuthContext);
const [Posts, setPosts] = useState();
const [isLoading, setisLoading] = useState(true);
//Loading screen will live here
useEffect(() => {
axios({
method: 'get',
url: 'http://192.168.1.112:3000/posts',
headers: {
Authorization: `${userAuth.token}`,
},
})
.then(response => {
setPosts(response.data.flat());
})
.then(setisLoading(false))
.catch(err => setPosts(err));
}, []);
return (
<View style={styles.PostContainer}>
<FlatList
contentContainerStyle={{height: '100%'}}
data={Posts}
renderItem={({item}) => <Post post={item} />}
/>
</View>
);
};
const styles = StyleSheet.create({
PostContainer: {
backgroundColor: 'grey',
flex: 1,
},
});
const Post = ({post}) => {
return (
<View style={styles.PostContainer}>
<View style={styles.PostHeader}>
<View style={styles.ProfileInfoView}>
<Text>Michael Wong</Text>
<Text>Yesterday at 6.30pm at point leo</Text>
</View>
</View>
<View style={styles.WaveInfo}>
<View>
<Text>Wave height </Text>
<Text> 6ft</Text>
</View>
<View>
<Text>tide </Text>
<Text>low</Text>
</View>
<View>
<Text>Break</Text>
<Text>crunchies</Text>
</View>
<View>
<Text>Wind </Text>
<Text>NE 10km/hr</Text>
</View>
</View>
<View style={styles.ImageView}>
<Image
source={require('../wave.webp')}
style={{flex: 1, width: undefined, height: undefined}}
/>
</View>
<View style={styles.FeedbackView}>
<Text>
<Icon name="thumbs-up" size={15} color="black" /> 13
</Text>
<Text>3 comments</Text>
</View>
<View style={styles.FooterView}>
<View style={styles.IconView}>
<Icon name="thumbs-up" size={30} color="white" />
<Icon name="envelope" size={30} color="white" />
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
PostContainer: {
backgroundColor: 'beige',
height: '80%',
},
PostHeader: {
height: '20%',
padding: '4%',
flexDirection: 'row',
},
Profileimg: {
height: 30,
width: 30,
borderRadius: 30,
},
ProfileInfoView: {
paddingLeft: '5%',
justifyContent: 'space-around',
},
WaveInfo: {
borderTopWidth: 1,
height: '12%',
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
},
ImageView: {
height: '60%',
width: '100%',
},
FeedbackView: {
height: '10%',
backgroundColor: 'beige',
flexDirection: 'row',
justifyContent: 'space-between',
padding: '3%',
alignItems: 'center',
},
FooterView: {
width: '100%',
height: '15%',
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'black',
borderBottomColor: 'grey',
borderBottomWidth: 12,
},
IconView: {
height: '100%',
width: '70%',
justifyContent: 'space-around',
alignItems: 'center',
flexDirection: 'row',
},
});
export default Post;

Adding ImageBackground to React Native Login Screen

I found this great code sample/layout -- see below -- for a React Native login screen. All I want to do is to have an ImageBackground as opposed to the current solid background.
When I add ImageBackground to the code, it throws everything off and instead of the image covering the entire screen, everything gets squished in the middle and all alingment gets out of whack. What am I doing wrong here?
Here's the original code with solid background:
import React from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
export default class App extends React.Component {
state={
email:"",
password:""
}
render(){
return (
<View style={styles.container}>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView} >
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({email:text})}/>
</View>
<View style={styles.inputView} >
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({password:text})}/>
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#003f5c',
alignItems: 'center',
justifyContent: 'center',
},
logo:{
fontWeight:"bold",
fontSize:50,
color:"#fb5b5a",
marginBottom:40
},
inputView:{
width:"80%",
backgroundColor:"#465881",
borderRadius:25,
height:50,
marginBottom:20,
justifyContent:"center",
padding:20
},
inputText:{
height:50,
color:"white"
},
forgot:{
color:"white",
fontSize:11
},
loginBtn:{
width:"80%",
backgroundColor:"#fb5b5a",
borderRadius:25,
height:50,
alignItems:"center",
justifyContent:"center",
marginTop:40,
marginBottom:10
},
loginText:{
color:"white"
}
});
This produces this nice layout:
And I simply add an image background with the following code which doesn't work at all:
<View style={styles.container}>
<ImageBackground
source={require("../../assets/images/background/teton_snake_dimmed.jpg")}
style={styles.imageBackground}
>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView} >
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({ email: text })} />
</View>
<View style={styles.inputView}>
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({ password: text })} />
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</ImageBackground>
</View>
And here's the updated styles. The only thing I add is the imageBackground:
container: {
flex: 1,
backgroundColor: '#003f5c',
alignItems: 'center',
justifyContent: 'center',
},
logo: {
fontWeight: "bold",
fontSize: 50,
color: "#fb5b5a",
marginBottom: 40
},
imageBackground: {
flex: 1,
resizeMode: "cover"
},
inputView: {
width: "80%",
backgroundColor: "#465881",
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: "center",
padding: 20
},
inputText: {
backgroundColor: "#465881",
height: 50,
color: "white"
},
forgot: {
color: "white",
fontSize: 11
},
loginBtn: {
width: "80%",
backgroundColor: "#fb5b5a",
borderRadius: 25,
height: 50,
alignItems: "center",
justifyContent: "center",
marginTop: 40,
marginBottom: 10
},
loginText: {
color: "white"
}
});
What am I doing wrong here?
P.S. Here's the original code published by #Alhydra:
https://github.com/Alhydra/React-Native-Login-Screen-Tutorial/blob/master/App.js
Here is an example replace the image with the image you want
snack: https://snack.expo.io/#ashwith00/intelligent-banana
code:
import React from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Image,
} from 'react-native';
export default class App extends React.Component {
state = {
email: '',
password: '',
};
render() {
return (
<View style={styles.container}>
<Image
style={styles.image}
source={{
uri:
'https://media.gettyimages.com/videos/loopable-color-gradient-background-animation-video-id1182636595?s=640x640',
}}
/>
<View style={styles.subContainer}>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={(text) => this.setState({ email: text })}
/>
</View>
<View style={styles.inputView}>
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={(text) => this.setState({ password: text })}
/>
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
image: {
flex: 1,
},
container: {
flex: 1,
backgroundColor: '#003f5c',
},
subContainer: {
...StyleSheet.absoluteFillObject,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
fontWeight: 'bold',
fontSize: 50,
color: '#fb5b5a',
marginBottom: 40,
},
inputView: {
width: '80%',
backgroundColor: '#465881',
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: 'center',
padding: 20,
},
inputText: {
height: 50,
color: 'white',
},
forgot: {
color: 'white',
fontSize: 11,
},
loginBtn: {
width: '80%',
backgroundColor: '#fb5b5a',
borderRadius: 25,
height: 50,
alignItems: 'center',
justifyContent: 'center',
marginTop: 40,
marginBottom: 10,
},
loginText: {
color: 'white',
},
});

Flatlist not re-rendering after deleting an item from the state

I'm working on a react native application,
In this application I have an image capturing the view, If the user captures an image it will be stored in the state hook, if something stored it will be displayed in Flatlist.
If we think the user needs to remove an item from the list, that I have provided a delete button. When a user clicks on it the item should be removed from the state and update the Flatlist.
My question is: after removing an item from the state my view is not re-render. I can guarantee that data is successfully removed from the state, but my Flatlist not updating.
My code as follows, please help me to find an answer. Thanks in advance.
below code used to remove the item from the state.
const [selectedFiles, setSelectedFiles] = useState([]);
const removeItemFromArray = (index: number) => {
let imagesArray = selectedFiles;
imagesArray.splice(index, 1);
setSelectedFiles(imagesArray);
}
flatlist
<FlatList
showsHorizontalScrollIndicator={false}
data={selectedFiles}
renderItem={({ item, index }) => {
return (
<ImagePreviewSlider
itemData={item}
viewImage={() => viewImage(index)}
deleteItem={() => removeItemFromArray(index)}
/>
);
}}
/>
---------- complete code --------------
photoUpload.tsx
import React, { useState } from "react";
import {
View,
Text,
StyleSheet,
ScrollView,
Image,
ImageBackground,
TouchableOpacity,
Modal,
FlatList
} from "react-native";
import ImagePicker from 'react-native-image-picker/lib/commonjs';
import ComponentStyles, { FONT_FAMILY, COLORS } from "../../../../constants/Component.styles";
import IconF from 'react-native-vector-icons/FontAwesome';
import ActionButton from "../../../../components/ActionButton";
import ImagePreviewSlider from "../../../../subComponents/ProgressBarWithImage";
import InspectionCheckListItem from './InspectionCheckListRow';
const ImageUpload = props => {
/**
* image capturing and upload tab view
*/
const [modalVisible, setModalVisible] = useState(false);
const [selectedFiles, setSelectedFiles] = useState([]);
/**
* used to open popup dialog / state hook will be updated.
*/
const openModal = () => {
// setModalVisible(true);
props.navigation.navigate('Inspection result');
}
/**
* when user click on previous button this method will be worked.
*/
const previousTab = () => {
props.navigation.navigate('Inspection checkList');
}
/**
* below method used to close the popup dialog.
*/
const colseModal = () => {
setModalVisible(false);
}
/**
* #chooseFile method is a alert dialog / here user can select camera or galery
* #ImagePicker method used to open camera and collect picture / select picture from galery(function)
*/
const chooseFile = () => {
const options = {
title: 'Select an option',
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, (response) => {
// console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else {
// let source = response;
// You can also display the image using data:
let source = {
uri: 'data:image/jpeg;base64,' + response.data
};
setImagesToHooks(source);
}
});
};
/**
*
* #param newImage base64- converted image
*/
const setImagesToHooks = (newImage) => {
// This will update the array. Refer the blog link for more information.
let imagesArray = [...selectedFiles, newImage];
setSelectedFiles(imagesArray);
};
const removeItemFromArray = (index: number) => {
let imagesArray = selectedFiles;
imagesArray.splice(index, 1);
setSelectedFiles(imagesArray);
}
const viewImage = (index: number) => {
console.log("view item : ######## : ");
}
return (
<View style={{ backgroundColor: COLORS.WHITE_BG, flex: 1, borderTopLeftRadius: 30, borderTopRightRadius: 30 }}>
<View style={{ flexDirection: 'row', width: '100%', height: '90%' }}>
<View style={{ width: '50%', height: '100%', padding: "2%" }}>
<TouchableOpacity style={{ width: '100%', height: 300, alignItems: 'center', justifyContent: 'center' }} onPress={chooseFile}>
<ImageBackground style={{ width: '100%', height: 300, alignItems: 'center', justifyContent: 'center' }} resizeMode={'stretch'}
source={require('../../../../assets/images/Rectangle_image_upload.png')} >
<IconF style={{ color: COLORS.ASH_AE }} name="camera" size={80} />
<Text style={{ color: COLORS.ASH_AE }}>Take image or upload from device</Text>
</ImageBackground>
</TouchableOpacity>
</View>
<View style={{ width: '50%', marginTop: 5, }}>
{/* <ProgressBar array={selectedFiles} deleteItem={(value) => deleteItemFromArray(value)}/> */}
<FlatList
showsHorizontalScrollIndicator={false}
data={selectedFiles}
renderItem={({ item, index }) => {
return (
<ImagePreviewSlider
itemData={item}
viewImage={() => viewImage(index)}
deleteItem={() => removeItemFromArray(index)}
/>
);
}}
/>
</View>
</View>
<View style={styles.actionButton}>
<ActionButton
title={'Previous'}
color={COLORS.PINK}
customBtnStyle={{
height: 65,
width: '85%',
}}
onPress={() => previousTab()}
/>
<ActionButton
title={'Next'}
color={COLORS.GREEN_42}
customBtnStyle={{
height: 65,
width: '100%',
}}
onPress={() => openModal()}
/>
</View>
<View>
<Modal
animationType="fade"
transparent={true}
visible={modalVisible} >
<View style={styles.modalContainer}>
<View style={styles.centeredView}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<TouchableOpacity style={{ flex: 0.2 }} onPress={colseModal}>
<Image source={require('../../../../assets/images/ic-close.png')} style={{ height: 20, width: 20, marginRight: 10 }} />
</TouchableOpacity>
</View>
<View style={styles.columnView}>
<Text style={styles.contentTitle}>Inspection of pharmacies</Text>
<Text style={styles.contentSubTitle}>Checklist:</Text>
<View style={styles.rowView}>
<View style={{ flex: 1, alignSelf: 'center' }} >
<Text style={styles.tableText}>Description</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }} >
<Text style={styles.tableText}>Validiry</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }} >
<Text style={styles.tableText}>Remark</Text>
</View>
</View>
</View>
<View style={{ flex: 2, width: '100%', flexDirection: 'column' }}>
{/* <InspectionCheckListItem array={InspectionList.items} /> */}
</View>
</View>
</View>
</Modal>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
modalContainer: {
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(100,100,100, 0.5)',
padding: 20,
},
centeredView: {
position: 'relative',
width: '90%',
height: '90%',
backgroundColor: COLORS.WHITE_FC,
padding: 20,
},
inspectionNumber: {
flex: 1.5,
fontSize: 18,
color: COLORS.BLUE_69,
fontFamily: FONT_FAMILY.BOLD
},
modalTitle: {
flex: 2,
fontSize: 12,
color: COLORS.GREEN_42,
fontFamily: FONT_FAMILY.BOLD
},
contentTitle: {
fontSize: 18,
color: COLORS.BLUE_69,
fontFamily: FONT_FAMILY.REGULAR,
},
contentSubTitle: {
fontSize: 18,
color: COLORS.BLUE_69,
fontFamily: FONT_FAMILY.BOLD,
},
columnView: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
},
rowView: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: '5%'
},
tableText: {
fontSize: 18,
color: COLORS.BLUE_69,
fontFamily: FONT_FAMILY.LIGHT,
justifyContent: 'center',
alignSelf: 'center'
},
actionButton: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'flex-end',
position: 'relative',
bottom: '2%',
left: 0,
}
});
export default ImageUpload;
ProgressBarWithImage.tsx
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity
} from "react-native";
import IconMC from 'react-native-vector-icons/MaterialCommunityIcons';
import { ProgressBar } from '#react-native-community/progress-bar-android';
import { COLORS, FONT_FAMILY } from "../constants/Component.styles";
const ProgressBarWithImage = props => {
return (
<View style={styles.container}>
<View style={{ justifyContent: 'center', alignItems: 'center', backgroundColor: COLORS.PINK, opacity: 0.3, height: 40, width: 40, borderRadius: 100 }}>
<TouchableOpacity onPress={props.viewImage}>
<IconMC style={{ color: COLORS.PINK, opacity: 100 }} name="file-image" size={30} />
</TouchableOpacity>
</View>
<View style={{ marginLeft: 20, }}>
<View style={{ flexDirection: 'row', alignItems: 'center', width: '100%' }}>
<Text style={{ fontSize: 15, color: COLORS.BLUE_2C, fontFamily: FONT_FAMILY.SEMI_BOLD }}>Photo01.PNG</Text>
<View style={{ flex: 1 }} />
<TouchableOpacity onPress={props.deleteItem}>
<IconMC style={{ color: COLORS.ASH_AE, opacity: 100, marginLeft: 60, }} name="close" size={20} />
</TouchableOpacity>
</View>
<Text style={{ fontSize: 15, color: COLORS.ASH_AE, fontFamily: FONT_FAMILY.SEMI_BOLD }}>7.5Mb</Text>
<ProgressBar
styleAttr="Horizontal"
indeterminate={false}
progress={1}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
width: '100%',
marginTop: 20,
},
});
export default ProgressBarWithImage;
Just use extraData prop of flatList to re-render flatList.
Simply add this state
const [refreshFlatlist, setRefreshFlatList] = useState(false);
And on in removeItemFromArray function add the following line
setRefreshFlatList(!refreshFlatlist)
finally, in flatList add this prop
extraData(refreshFlatlist)