I've had this problem for a while with KeyboardAwareScrollView, where it has some extra padding at the bottom (yellow). Here I want my form to be always at the bottom of the screen, this it seems this padding does not permit this.
export const LoginView: React.FC = () => {
return (
<View style={styles.container}>
<KeyboardAwareScrollView
style={styles.scrollContainer}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
<View
style={{
justifyContent: "space-between",
backgroundColor: "green",
}}
>
<View style={styles.imageContainer}>
<Image></Image>
</View>
<View style={styles.formConstainer}>
<Formik></Formik>
</View>
</View>
</KeyboardAwareScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: {
backgroundColor: "yellow",
},
imageContainer: {
alignItems: "center",
justifyContent: "center",
},
formConstainer: {},
});
Here's how it looks like right now.
Just change KeyboardAwareScrollView style to contentContainerStyle ( These styles will be applied to the scroll view content container which wraps all of the child views. )
and add flex to view inside it.
export const LoginView: React.FC = () => {
return (
<View style={styles.container}>
<KeyboardAwareScrollView
contentContainerStyle={styles.scrollContainer} //style changed to contentContainerStyle
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
>
<View
style={{
justifyContent: "space-between",
backgroundColor: "green",
flex:1 //flex added
}}
>
<View style={styles.imageContainer}>
<Image></Image>
</View>
<View style={styles.formConstainer}>
<Formik></Formik>
</View>
</View>
</KeyboardAwareScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: {
backgroundColor: "yellow",
flexGrow:1 //added flexGrow
},
imageContainer: {
alignItems: "center",
justifyContent: "center",
flex:2 //flex added
},
formConstainer: {
flex:1 //flex added
},
});
Make the contentInset to be dynamic based on the keyboard hide and view.
set the contentBottom value based on your design.
Values in the solution are based on my design
const [contentBottom, setContentBottom] = useState(0);
<KeyboardAwareScrollView
style={{
flex: 1,
backgroundColor: Color.white,
}}
keyboardOpeningTime={0}
extraScrollHeight={150}
enableResetScrollToCoords
onKeyboardWillHide={() => setContentBottom(0)}
onKeyboardWillShow={() => setContentBottom(200)}
contentInset={{ bottom: contentBottom }}
>
Related
I am unable to get my Flatlist to scroll in my expo react native app. At the moment it is just static, displaying a grid of images int he Flatlist with no scrolling functionality. Please can someone advise?
I am unable to get my Flatlist to scroll in my expo react native app. At the moment it is just static, displaying a grid of images int he Flatlist with no scrolling functionality. Please can someone advise?
import { StyleSheet, Text, View, Button, TextInput, TouchableWithoutFeedback, Keyboard, FlatList, ActivityIndicator } from 'react-native';
import { Image } from '#rneui/themed';
import ImageAPI from '../shared-components/ImageAPI';
export default function Home({ navigation }) {
const onCreate = () => {
console.log('create my image now');
};
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
{/** Enter text prompt */}
<View style={styles.section1}>
<View style={styles.txtInputView}>
<TextInput
style={styles.txtInput}
placeholder='Enter a prompt - a description of what you want to create'
multiline={true}
numberOfLines={4}
/>
</View>
<View style={styles.buttonView}>
<Text
style={styles.createBtnText}
onPress={onCreate}
>Create</Text>
</View>
</View>
{/** PROMPT EXAMPLES */}
<View style={styles.section2}>
<View style={styles.section2_sub0}>
<Text style={styles.promptEgTxt}>Prompt Examples</Text>
</View>
<View style={styles.section2_sub1}>
<ImageAPI />
</View>
</View>
</View>
</TouchableWithoutFeedback>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
section1: {
flex: 2,
width: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ffc6e2',
},
section2: {
flex: 5,
width: '100%',
backgroundColor: '#F8DB93',
},
// section3: {
// flex: 3,
// backgroundColor: '#BCF893',
// },
txtInputView: {
flex: 3,
width: '85%',
height: '50%',
alignItems: 'center',
justifyContent: 'center',
marginTop: 20,
marginBottom: 20
},
buttonView: {
flex: 2,
width: '70%',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 20,
backgroundColor: '#EE4A4A',
borderRadius: 40
},
txtInput: {
borderColor: '#AAAAAA',
borderWidth: 2,
padding: 10,
borderRadius: 15,
// width: '85%',
// height: '50%',
width: '100%',
height: '100%',
fontSize: 15,
},
createBtnText: {
fontSize: 18,
fontWeight: 'bold',
// backgroundColor: '#EEEC4A'
},
section2_sub0: {
flex: 1,
width: '100%',
height: '100%',
backgroundColor: '#EEEC4A',
justifyContent: 'center',
},
promptEgTxt: {
fontSize: 15,
fontWeight: 'bold',
marginLeft: 10
},
section2_sub1: {
flex: 8,
width: '100%',
height: '100%',
backgroundColor: '#A9F889'
},
});
This is the ImageAPI.js file:
import React from 'react';
import { FlatList, SafeAreaView, StyleSheet, ActivityIndicator, View, ScrollView } from 'react-native';
import { Image } from '#rneui/themed';
const BASE_URI = 'https://source.unsplash.com/random?sig=';
const ImageAPI = () => {
return (
<>
<SafeAreaView>
<FlatList
data={[...new Array(10)].map((_, i) => i.toString())}
style={styles.list}
numColumns={2}
keyExtractor={(e) => e}
renderItem={({ item }) => (
<Image
transition={true}
source={{ uri: BASE_URI + item }}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
list: {
width: '100%',
backgroundColor: '#000',
},
item: {
aspectRatio: 1,
width: '100%',
flex: 1,
},
});
export default ImageAPI
you need to give it a fixed height and set the contentContainerStyle prop to { flexGrow: 1 }. This will allow the content inside the FlatList to exceed the bounds of the container and be scrollable.
<View style={styles.section2_sub1}>
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
data={data}
renderItem={({ item }) => <ImageAPI data={item} />}
keyExtractor={(item) => item.id}
/>
</View>
Try adding flex according to your requirement to your <SafeAreaView> which is the parent to your <Flatlist> Something like this:
<>
<SafeAreaView style = {{flex: 8}} >
<FlatList
data={[...new Array(10)].map((_, i) => i.toString())}
style={styles.list}
numColumns={2}
keyExtractor={(e) => e}
renderItem={({ item }) => (
<Image
transition={true}
source={{ uri: BASE_URI + item }}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</SafeAreaView>
</>
Or remove the SafeAreaView if not required.
Both should work.
I want to put my button at the bottom of the screen, that button it should be fixed, i try like this:
<SafeAreaView>
<FlatList
horizontal
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
<View style={styles.mainConatinerStyle}>
<Button style={styles.floatingMenuButtonStyle} onPress={() => { }}>
Add
</Button>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
mainConatinerStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}, floatingMenuButtonStyle: {
position: 'static',
bottom: 10,
right: 10
}
})
but it does not show me the button, there is not the button in the screen, what i am doing bad?
You can use position: 'absolute' please try to update as following:
<SafeAreaView style={styles.container}>
<FlatList
horizontal
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
<Button style={styles.floatingMenuButtonStyle} onPress={() => { }}>
Add
</Button>
</SafeAreaView>
const styles = StyleSheet.create({
container: {
flex: 1
},
mainConatinerStyle: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
floatingMenuButtonStyle: {
position: 'absolute', // should be 'absolute'
bottom: 10,
right: 10
}
})
I have an image in each TouchableOpacity and I would like to change the picture in every onPress function so she could looked like shes pressed in (for example: remove the color from to picture and changes it to black and white or make a light gray shadow on the picture ).
and Reverse (when you click shes changing back to the original picture (Press:true/false).
I have a stateless Component and no class.
My Component :
export default function Recipie({ navigation, route }) {
const recipies = GetRecipies();
return (
<View style={{ flexGrow: 1, flex: 1 }}>
<ScrollView>
{recipies.map((u, i) => {
return (
<View key={i}>
<Text
onPress={navigation.navigate}
style={{
fontSize: 25,
fontFamily: "Cochin",
textAlign: "center",
}}
>
{u._recipieName}
</Text>
<TouchableOpacity
onPress={() => {
navigation.navigate("SingleRecipieScreen", { u });
}}
>
<Image
style={{
height: 200,
width: 350,
borderRadius: 80,
alignSelf: "center",
}}
source={{ uri: u._imgUrl }}
/>
</TouchableOpacity>
<Text
style={{
fontSize: 17,
fontFamily: "Cochin",
textAlign: "center",
}}
>
{u._recipieDescription}
</Text>
<TouchableOpacity
style={{ flex: 1, flexDirection: "column", flexGrow: 1 }}
>
{Show(u._preparationTime)}
</TouchableOpacity>
</View>
);
})}
</ScrollView>
</View>
);
}
Try to use position absolute in View to cover button , and useState for styles, example :
import React, { useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View,Image } from "react-native";
const App = () => {
const [isPressed, setIsPressed] = useState(0);
const onPress = () => setIsPressed(!isPressed);
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={onPress}
>
<View style={isPressed && styles.pressedButtonStyle} />
<Text> {isPressed ? "Pressed" : " Press Here"}</Text>
<Image
style={ styles.tinyLogo}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingHorizontal: 10,
},
button: {
alignItems: "center",
backgroundColor: "#DDDDDD",
},
tinyLogo: {
width: 50,
height: 50,
},
pressedButtonStyle: {
position:"absolute",
width:"100%",
height:"100%",
backgroundColor:'black',
opacity:0.6,
zIndex:100,
}
});
https://snack.expo.dev/ixeOwAg3o
I am new to react native. I am trying to set the text in a view, but the text is overflowing outside the view like in the image below. Tried flexWrap:'wrap and flexShrink:1 but it is also not working. I have implemented as follows:
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => navigate('BlogDetails', item)}>
<Card style={{flexDirection:'row',flexShrink:1}}>
<CardSection>
<View style={styles.thumbnailContainerStyle}>
<Image
style={styles.thumbnailStyle}
source={{ uri: item.imagepath }}
/>
</View>
<CardSection>
<View style={styles.headerContentStyle}>
<Text numberOfLines={5} style={styles.headerTextStyle}>{item.news_title}</Text>
{/* <Text>{item.blog_description}</Text> */}
</View>
</CardSection>
</CardSection>
</Card>
</TouchableOpacity>
)}
keyExtractor={(item, index) => index.toString()}
>
</FlatList>
</View>
My style :
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
minHeight: 1,
minWidth: 1,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginRight: 10
},
headerContentStyle: {
flexDirection: 'column',
flexWrap:'wrap',
flexShrink:1,
justifyContent: 'center',
alignItems: 'flex-start'
},
thumbnailStyle: {
width: 130,
height: 130,
resizeMode:"contain"
},
imageStyle: {
height: 100,
flex: 1,
width: null
},
cardStyle:{
width:'100%',
height:200,
},
headerTextStyle:{
fontSize:20,
flexWrap: 'wrap',
flexShrink: 1
},
infoText: {
fontSize: 14
}
});
Try this :
Add flexShrink:1 in parent wrapper and in text component do flex:1 and flexWrap:'wrap'
use only flexWrap : 'wrap' for wrap your text use this css for your view and text
headerContentStyle: {
flexWrap : 'wrap'
},
headerTextStyle:{
fontSize:20,
},
So I am using React Native Section List and following is my Code of ListEmptyContent
// define your styles
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
marginLeft: 10,
marginRight: 10,
},
imageStyle: {
width: 140,
height: 120,
},
titleStyle: {
fontSize: 14,
color: '#363a45',
},
subTitleStyle: {
fontSize: 12,
color: '#898d97',
},
});
// create a component
const GPEmtptyTransaction = ({ firstLine, secondLine }) => {
return (
<View style={styles.container}>
<Image source={images.emptyTransactionIcon} style={styles.imageStyle} />
<Text style={styles.titleStyle}>{firstLine}</Text>
<Text style={styles.subTitleStyle}>{secondLine}</Text>
</View>
);
};
But when EmptyTemplate is rendered it is rendered on Top and not stretching to full screen.
This works for me, apply flexGrow: 1 to contentContainerStyle
<FlatList
data={this.props.operations}
contentContainerStyle={{ flexGrow: 1 }}
ListEmptyComponent={<EmptyPlaceHolder />}
renderItem={this.renderOperationItem} />
For me what worked was adding some styles to the contentContainerStyle as well:
contentContainerStyle={{ flex: 1, justifyContent: 'center' }}
The SectionList complete setup on my end was:
<SectionList
showsVerticalScrollIndicator={false}
sections={filteredData}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
initialNumToRender={15}
contentContainerStyle={{ flex: 1, justifyContent: 'center' }}
ListEmptyComponent={() => (
<EmptyListComponent
icon={<Document />}
message={'Your roster is empty'}
/>
)}
/>
You can add contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} prop to FlatList
I got success with the simple trick as below
import { Dimensions } from "react-native";
const SCREEN_HEIGHT = Dimensions.get("window").height;
than I declare the empty component
_listEmptyComponent = () => {
return (
<View
style={{
justifyContent: "center",
alignItems: "center",
height: SCREEN_HEIGHT , //responsible for 100% height
backgroundColor: "#ddd"
}}
>
<Text
style={{
justifyContent: "center",
alignItems: "center",
fontSize: 20
}}
>
No Contracts Found
</Text>
</View>
);
And at last Flatlist look like :
<FlatList
extraData={this.props.contracts}
data={this.props.contracts}
ListEmptyComponent={this._listEmptyComponent.bind(this)}
renderItem={({ item }) => (
<Text>{item.contractName}>
<Text/>
)}
keyExtractor={(item, index) => item.id}
/>