React Native Sticky Footer Input got covered by Keyboard even using KeyboardAvoidingView - css

I have a basic chat application and when I open the keyboard I want the Sticky Chat Footer to persist at the top of the keyboard but its still being covered even when I use KeyboardAvoidingView.
Here is the image below:
And here is the image when keyboard is open:
Here is my component code below:
<SafeAreaView style={styles.scrollWrapper}>
<KeyboardAvoidingView
style={styles.scrollWrapper}
behavior="height"
keyboardVerticalOffset={headerHeight + 20}
>
<View style={styles.chatBar}>
<IconButton Icon={ButtonAdd} size={32} onPress={() => {}} />
{isKeyboardVisible ? (
<>
<RoundedInput
ref={inputRef}
itemStyle={styles.chatInput}
placeholder="type something here..."
RightComponent={(
<IconButton
Icon={EmojiIcon}
size={normalize(16.5)}
onPress={() => {}}
/>
)}
/>
<TouchableOpacity
activeOpacity={0.4}
onPress={handleKeyboardVisibility}
>
<Icon
style={styles.icon}
name="send-circle"
size={normalize(34)}
color="#F48C2D"
/>
</TouchableOpacity>
</>
) : (
<>
<IconButton
Icon={KeyboardIcon}
size={32}
onPress={handleKeyboardVisibility}
/>
<IconButton Icon={ChatCamera} size={32} onPress={() => {}} />
<IconButton Icon={GalleryIcon} size={32} onPress={() => {}} />
<IconButton Icon={GifIcon} size={32} onPress={() => {}} />
<IconButton Icon={LocationIcon} size={32} onPress={() => {}} />
</>
)}
</View>
</KeyboardAvoidingView>
</SafeAreaView>
and here is my style
const styles = StyleSheet.create({
header: {
...headerStyles.homeHeaderWrapper,
backgroundColor: '#F9F9F9',
borderBottomColor: '#D0D1D1',
},
scrollWrapper: {
flexGrow: 1,
backgroundColor: 'white',
},
dateWrapper: {
marginTop: normalize(12),
...helpers.center,
},
dateTxt: {
...fontHelper(10, typographyFonts.openSansRegular, '#212121', 0).font,
},
messageWrapper: {
flexDirection: 'row',
padding: normalize(12),
},
image: {
height: normalize(33),
width: normalize(33),
overflow: 'hidden',
borderRadius: 100,
alignSelf: 'center',
marginTop: normalize(12),
},
chatBubble: {
marginLeft: normalize(8),
maxWidth: '75%',
// height: normalize(77),
backgroundColor: '#F2F5F8',
borderRadius: 14,
// ...helpers.center,
padding: normalize(12),
marginVertical: normalize(5),
},
chatMsg: {
...fontHelper(13, typographyFonts.openSansRegular, '#212121', 0).font,
},
chatBar: {
height: normalize(65),
shadowOffset: { width: normalize(0), height: normalize(-1.25) },
// borderWidth: 5,
// borderBottomColor: 'red',
borderTopWidth: normalize(0.3),
borderTopColor: colors.alternative,
shadowColor: 'rgba(186,190,214,0.70)',
shadowOpacity: normalize(0.2),
shadowRadius: 2,
elevation: 5,
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
zIndex: 999,
},
chatInput: {
height: normalize(35),
backgroundColor: '#FFFFFF',
borderColor: '#F48C2D',
borderWidth: 1,
width: '70%',
},
icon: {
width: normalize(34),
height: normalize(34),
},
});
I also already tried using react-native-keyboard-aware-scrollview but it didn't help as well.
Appreciate if someone could help.

I got the same issue.
Try this workaround.
You need to position your component on the top of the keyboard,
but it will depend on the size of device keyboard
import { Keyboard, Animated } from 'react-native'
...
useEffect(() => {
Keyboard.addListener('keyboardWillShow', _keyboardWillShow);
Keyboard.addListener('keyboardWillHide', _keyboardWillHide);
return () => {
Keyboard.removeListener('keyboardWillShow', _keyboardWillShow);
Keyboard.removeListener('keyboardWillHide', _keyboardWillHide);
}
}, []);
const _keyboardWillShow = (event) => {
const height = event.endCoordinates.height;
posComponent(height);
};
const _keyboardWillHide = (event) => {
posComponent(0);
};
const animateButton = (value) => {
Animated.spring(your_variable, {
toValue: value,
tension: 50,
friction: 10,
}).start();
}
then on your view component chatbar
<Animated.View style={{
...styles.chatBar,
...(Platform.OS === 'ios' && { bottom: your_variable })}>
...
</Animated.View>

Related

React Native - Pressable is not clickable on Android

What I'm building:
I'm creating a card that will render with a question mark at top of it and when the user press it, the card will flip with animation and show some information.
Code:
From a code perspective it looks like this:
import { View, StyleSheet, Text, Pressable, Animated } from 'react-native';
import { FontAwesome } from '#expo/vector-icons';
import { GlobalStyles } from '../../constants/styles';
import { useTranslation } from 'react-i18next';
export default Card = ({ isSpy, guessingItem, onPress }) => {
const { t } = useTranslation();
let currentValue = 0;
const animatedValue = new Animated.Value(0);
animatedValue.addListener((v) => (currentValue = v.value));
const frontInterpolate = animatedValue.interpolate({
inputRange: [0, 180],
outputRange: ['0deg', '180deg'],
});
const backInterpolate = animatedValue.interpolate({
inputRange: [0, 180],
outputRange: ['180deg', '360deg'],
});
const frontAnimatedStyles = {
transform: [{ rotateY: frontInterpolate }],
};
const backAnimatedStyles = {
transform: [{ rotateY: backInterpolate }],
};
const flipCard = () => {
console.log(currentValue);
if (currentValue >= 90) {
Animated.spring(animatedValue, {
toValue: 0,
tension: 10,
friction: 8,
useNativeDriver: false,
}).start();
setTimeout(() => onPress(), 600);
} else {
Animated.spring(animatedValue, {
toValue: 180,
tension: 10,
friction: 8,
useNativeDriver: false,
}).start();
}
};
return (
<View style={styles.constainer}>
<Pressable onPress={flipCard} style={{ backgroundColor: 'red' }}>
<View style={GlobalStyles.styles.flexbox}>
<Animated.View style={[styles.innerContainer, frontAnimatedStyles]}>
<FontAwesome name="question" size={160} />
</Animated.View>
</View>
</Pressable>
<Pressable onPress={flipCard}>
<View style={GlobalStyles.styles.flexbox}>
<Animated.View style={[backAnimatedStyles, styles.innerContainer, styles.innerContainerBack]}>
<View style={styles.constainer}>
{!isSpy && (
<>
<FontAwesome name={guessingItem.section.icon} size={60} />
<Text style={styles.itemName}>{guessingItem.name}</Text>
</>
)}
{isSpy && (
<>
<FontAwesome name="user-secret" size={60} />
<Text style={styles.placeName}>{t('youAreSpy')}</Text>
</>
)}
</View>
</Animated.View>
</View>
</Pressable>
</View>
);
};
const styles = StyleSheet.create({
constainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
innerContainer: {
height: 300,
width: 230,
marginVertical: 50,
padding: 60,
borderWidth: 6,
borderColor: GlobalStyles.colors.primary50,
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
backfaceVisibility: 'hidden',
},
innerContainerBack: {
position: 'absolute',
right: -115,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
},
itemName: {
marginTop: 20,
fontSize: 18,
alignItems: 'center',
color: GlobalStyles.colors.primary50,
},
pressed: {},
});
What is an issue:
On-screen below you can see a pressable element with red background.
If I click on any part of this red part, the card would flip. If I test it on Android, clicking on anything inside the white border would not trigger a flip. Only clicking outside of that white border but still inside the red background would trigger a flip.
The question is: Why it behaves differently when I am using basic react-native elements? How can I fix that so clicking would always work for the inside click?
I tested this component on my side and it works well. I think there is no problem with the Card component. Please check the parent component of the Card.
I only changed "right" value from -115 to 0 in the style of innerContainerBack.
innerContainerBack: {
position: 'absolute',
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
}
And you'd better use only one Pressable Component and remove the View component in the Pressable. So my ultimate solution is
import { View, StyleSheet, Text, Pressable, Animated } from 'react-native';
import { FontAwesome } from '#expo/vector-icons';
import { GlobalStyles } from '../../constants/styles';
import { useTranslation } from 'react-i18next';
export default Card = ({ isSpy, guessingItem, onPress }) => {
const { t } = useTranslation();
let currentValue = 0;
const animatedValue = new Animated.Value(0);
animatedValue.addListener((v) => (currentValue = v.value));
const frontInterpolate = animatedValue.interpolate({
inputRange: [0, 180],
outputRange: ['0deg', '180deg'],
});
const backInterpolate = animatedValue.interpolate({
inputRange: [0, 180],
outputRange: ['180deg', '360deg'],
});
const frontAnimatedStyles = {
transform: [{ rotateY: frontInterpolate }],
};
const backAnimatedStyles = {
transform: [{ rotateY: backInterpolate }],
};
const flipCard = () => {
console.log(currentValue);
if (currentValue >= 90) {
Animated.spring(animatedValue, {
toValue: 0,
tension: 10,
friction: 8,
useNativeDriver: false,
}).start();
setTimeout(() => onPress(), 600);
} else {
Animated.spring(animatedValue, {
toValue: 180,
tension: 10,
friction: 8,
useNativeDriver: false,
}).start();
}
};
return (
<View style={styles.constainer}>
<Pressable onPress={flipCard} style={{ backgroundColor: 'red' }}>
<Animated.View style={[styles.innerContainer, frontAnimatedStyles]}>
<FontAwesome name="question" size={160} />
</Animated.View>
<Animated.View style={[backAnimatedStyles, styles.innerContainer, styles.innerContainerBack]}>
<View style={styles.constainer}>
{!isSpy && (
<>
<FontAwesome name={guessingItem.section.icon} size={60} />
<Text style={styles.itemName}>{guessingItem.name}</Text>
</>
)}
{isSpy && (
<>
<FontAwesome name="user-secret" size={60} />
<Text style={styles.placeName}>{t('youAreSpy')}</Text>
</>
)}
</View>
</Animated.View>
</Pressable>
</View>
);
};
const styles = StyleSheet.create({
constainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
innerContainer: {
height: 300,
width: 230,
marginVertical: 50,
padding: 60,
borderWidth: 6,
borderColor: GlobalStyles.colors.primary50,
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
backfaceVisibility: 'hidden',
},
innerContainerBack: {
position: 'absolute',
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
},
itemName: {
marginTop: 20,
fontSize: 18,
alignItems: 'center',
color: GlobalStyles.colors.primary50,
},
pressed: {},
});

react native. how to make the left side non scrollable at table below

so I have a question/answer table below and I want to make the left part of the table to stick there. Each row is mapped individually(1st row- title, than the radio buttons for that, 2nd row than the buttons and so on. in reactJs I would put a position sticky or fixed to solve the problem but i dont know how to solve it in native.
a snack environment if anyone needs it https://snack.expo.dev/Mz0nR6Fj5
Here is the code
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
import Constants from 'expo-constants';
import { Button, RadioButton } from 'react-native-paper';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
const [res, setRes] = useState([]);
let answers = ['good', ' bad', 'ehh'];
let question = [
'how are you',
'how the weather',
'how was the day',
'what do you think about ....',
];
useEffect(() => {
setRes(
question.map((title) => ({
title,
...answers.reduce((p, c) => ((p[c] = 0), p), {}),
}))
);
}, []);
const handleClick = (i, x) => {
setRes(
res.map((data) => {
if (i.title === data.title && i[x] === 0) {
const title = i.title;
for (const property in i) {
i[property] = 0;
}
i[x] = 1;
i.title = title;
}
// else if (i.title === data.title && i[x] === 1) {
// i[x] = 0;
// }
return data;
})
);
const yy = [];
console.log(res);
res.map(({ title, ...i }) => {
yy.push(Object.values(i).flat());
});
console.log(yy);
};
const show = () => {
const yy = [];
console.log(res);
res.map(({ title, ...i }) => {
yy.push(Object.values(i).flat());
});
console.log(yy);
// console.log(result);
// console.log('njeDheZero___ ', njeDheZero);
};
// console.table(players);
return (
<View>
<ScrollView horizontal={true} style={styles.container}>
<View
style={{
backgroundColor: 'white',
flexDirection: 'column',
borderTopWidth: 1,
borderLeftWidth: 1,
borderColor: '#ccc',
marginRight: 30,
}}>
<View style={{ flexDirection: 'row' }}>
<View
style={{
borderBottomWidth: 1,
borderRightWidth: 1,
borderColor: '#ccc',
width: 200,
}}>
<Text style={{ padding: 10 }}>-</Text>
</View>
{answers.map((subq) => (
<View
key={subq}
style={{
borderBottomWidth: 1,
borderRightWidth: 1,
borderColor: '#ccc',
width: 120,
}}>
<Text style={{ padding: 10 }}>{subq}</Text>
</View>
))}
</View>
{res.length > 0 ? (
<>
{res.map((i, inda) => {
// console.log("render",i.title)
return (
<View key={inda} style={{ flexDirection: 'row' }}>
<View
style={{
borderBottomWidth: 1,
borderRightWidth: 1,
borderColor: '#ccc',
width: 200,
}}>
<Text style={{ padding: 10 }}>{i?.title}</Text>
</View>
{answers.map((x, indq) => {
return (
<View
style={{
borderBottomWidth: 1,
borderRightWidth: 1,
borderColor: '#ccc',
width: 120,
justifyContent: 'center',
alignItems: 'center',
}}>
<RadioButton.Group>
<RadioButton
// value={i[x]}
status={i[x] === 1 ? 'checked' : 'unchecked'}
onPress={() => {
handleClick(i, x);
}}
/>
</RadioButton.Group>
</View>
);
})}
</View>
);
})}
</>
) : (
<Text>LOADING</Text>
)}
</View>
</ScrollView>
<Button onPress={show}>
<Text>SHOW</Text>
</Button>
</View>
);
}
const styles = StyleSheet.create({
// container: {
// flex: 1,
// justifyContent: 'center',
// paddingTop: Constants.statusBarHeight,
// backgroundColor: '#ecf0f1',
// padding: 8,
// },
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});

Expo Google places autocomplete - listView not clicable

I am trying to use the GooglePlacesAutocomplete, but once I make the address query, for example: "São C" and the "listView" return something like: "São Caetano, São Paulo ...", but when I try to select one option it seems like the list is not visible, because and the selection do not affect the item list.
this is the code I am using:
import * as React from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { colors, device, fonts } from '../constants';
// icons
import SvgTruck from './icons/Svg.Truck';
//const { onLocationSelected } = this.props
// constants
const GOOGLE_MAPS_APIKEY = '[API KEY]'
const WhereTo = () => (
<View style={styles.container}>
<View style={styles.containerBanner}>
<Text style={styles.bannerText}>15% off, up to $6.00</Text>
<Text style={styles.bannerMuted}>3 days</Text>
</View>
<View style={styles.containerInput} >
<View style={styles.containerSquare}>
<View style={styles.square} />
</View>
<GooglePlacesAutocomplete
styles={{
textInputContainer: {
flex: 1,
backgroundColor: 'transparent',
height: 54,
marginHorizontal: 20,
borderTopWidth: 0,
borderBottomWidth:0
},
textInput: {
height: 45,
left:0,
margin: 0,
borderRadius: 0,
paddingTop: 0,
paddingBottom: 0,
paddingLeft: 0,
paddingRight: 0,
padding: 0,
marginTop: 0,
marginLeft: 0,
marginRight: 0,
fontSize:18
},
listView: {
position:'absolute',
marginTop: 50
},
description: {
fontSize:16
},
row: {
padding: 18,
height:58
}
}}
placeholder="Para onde?"
onPress={(data, details) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
query={{
key: GOOGLE_MAPS_APIKEY,
language: 'pt',
components: "country:br"
}}
textInputProps={{
autoCapitalize: "none",
autoCorrect: false
}}
fetchDetails
enablePoweredByContainer={false}
/>
<View style={styles.containerIcon}>
<SvgTruck />
</View>
</View>
</View>
);
const styles = StyleSheet.create({
container: {
top: Platform.select({ ios: 60, android: 40 }),
alignSelf: 'center',
position: 'absolute',
shadowColor: colors.black,
shadowOffset: { height: 2, width: 0 },
shadowOpacity: 0.2,
shadowRadius: 8,
top: device.iPhoneX ? 144 : 120,
width: device.width - 40
},
containerBanner: {
backgroundColor: colors.green,
borderTopLeftRadius: 4,
borderTopRightRadius: 4,
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 8
},
bannerText: {
color: colors.white,
fontFamily: fonts.uberMedium,
fontSize: 12
},
bannerMuted: {
color: colors.mint,
fontFamily: fonts.uberMedium,
fontSize: 12
},
containerInput: {
alignItems: 'center',
backgroundColor: colors.white,
flexDirection: 'row',
height: 48
},
containerSquare: {
alignItems: 'center',
flex: 0.15
},
square: {
backgroundColor: colors.black,
height: 8,
width: 8
},
containerIcon: {
alignItems: 'center',
borderLeftColor: colors.greyMercury,
borderLeftWidth: 1,
flex: 0.2
}
});
export default WhereTo;
Can anyone trying to help me to solve it?
I recreated the Expo project and now it works, I could not found the root cause, but once that other project was made by other person and Expo make it easy to do and configure, it was fast enoght to create.
export default function AskForDriver () {
const [location, setLocation] = useState("");
const [errorMsg, setErrorMsg] = useState("");
useEffect(() => {
(async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
})();
}, []);
let text = 'Waiting..';
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = JSON.stringify(location);
console.log('location - latitude: ', location.coords.latitude)
console.log('location - longitude: ', location.coords.longitude)
}
return (
<View style={styles.container}>
<View style={styles.mainHeader}>
<Text style={styles.fontHeader}>Incluir flatlist com promoções e mensagens de incentivos</Text>
</View>
<View style={styles.searchHeader}>
<GooglePlacesAutocomplete
currentLocation
//styles={styles.placesautocomplete}
styles={{
textInputContainer: {
backgroundColor: 'grey',
},
placesautocomplete: {
flex:1,
},
textInput: {
height: 38,
color: '#5d5d5d',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#1faadb',
},
}}
placeholder='Search'
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
query={{
key: 'YOUR API KEY',
language: 'pt',
components: 'country:br',
}}
/>
</View>
<MapView
style={styles.mapStyle}
showsMyLocationButton
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
</MapView>
{//<Text>{text}</Text>
}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
position: 'absolute',
alignContent:'center',
margin:0
},
mainHeader: {
backgroundColor: '#10002b',
padding:10,
},
fontHeader: {
color: '#e0aaff',
fontSize: 15,
},
searchHeader: {
borderColor: '#333',
borderWidth:5,
},
mapStyle: {
flex:1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});

Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference , react redux and when use connect

when i want to configuration react redux and set connect in my Routes
component i get this err ,
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { Router, Scene, Actions } from 'react-native-router-flux';
import { Text, View, Image, TouchableOpacity, ImageBackground, AsyncStorage } from 'react-native';
import SendNumber from './src/container/SendNumber';
import EnterCode from './src/container/EnterCode';
import Home from './src/container/Home';
import Profile from './src/container/Profile';
import ResultItemsPage from './src/container/ResultItemsPage'
import Details from './src/container/Details'
//back button
const backButton = () => (
<TouchableOpacity
onPress={() => Actions.pop()}
style={{ width: 30, height: 20, marginLeft: 20 }}
>
<View style={{ alignItems: 'center' }}>
<Image
source={require('./Assets/Images/left-arrow.png')}
style={{ width: 30, height: 20 }}
/>
{/*
<Icon name='ios-arrow-round-back' style={{ color: '#fff' }} />
*/}
</View>
</TouchableOpacity>
);
const backButtonDetail = () => (
<TouchableOpacity
style={{
backgroundColor: '#33333320',
padding: 10,
width: 50,
height: 50,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
top: 10,
start: 10,
}} onPress={() => Actions.pop()} >
<Image style={{
width: 30,
resizeMode: 'contain'
}}
source={require('./Assets/Images/left-arrow-white.png')} />
</TouchableOpacity>
)
class Routes extends Component {
constructor(props) {
super(props)
this.state = {
login: false
}
}
_storeData = async () => {
try {
await AsyncStorage.setItem('login', 'true');
} catch (error) {
// Error saving data
}
};
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('TASKS');
alert(value)
} catch (error) {
// Error retrieving data
}
};
componentWillMount() {
this._storeData();
this._retrieveData();
}
render() {
return (
<Router>
<Scene key="root" >
<Scene key="SendNumber"
component={SendNumber}
title="Send Number"
hideNavBar={true}
initial={true}
/>
<Scene key="EnterCode" component={EnterCode}
title=""
titleStyle={{ color: 'transparent' }}
renderBackButton={() => backButton()}
navigationBarStyle={styles.login_style_bar}
sceneStyle={styles.login_scene_style}
/>
<Scene key="Home"
component={Home}
title="home"
hideNavBar={true}
/>
<Scene key="Profile" component={Profile}
title=""
titleStyle={{ color: 'transparent' }}
renderBackButton={() => backButton()}
navigationBarStyle={styles.login_style_bar}
sceneStyle={styles.login_scene_style}
/>
<Scene key="ResultItemsPage" component={ResultItemsPage}
title=""
titleStyle={{ color: 'transparent' }}
renderBackButton={() => backButton()}
navigationBarStyle={styles.login_style_bar}
sceneStyle={styles.login_scene_style}
onRight={() => alert('right')}
// rightButtonImage={require('./Assets/Images/bell.png')}
renderRightButton={() => (
<TouchableOpacity style={styles.notification_box}
onPress={() => alert('توجهات')}>
<ImageBackground
style={styles.bell}
source={require('./Assets/Images/bell.png')}
>
<View style={styles.notification} >
<Text style={styles.notification_text} >3</Text>
</View>
</ImageBackground>
</TouchableOpacity>
)}
/>
<Scene key="Details" component={Details}
title=""
titleStyle={{ color: 'red' }}
renderBackButton={() => backButtonDetail()}
navigationBarStyle={styles.login_style_bar_detail}
sceneStyle={styles.login_scene_style}
/>
</Scene>
</Router >
)
}
}
const mapStateToProps = state => {
return {
status: state.number.loginStatus
}
}
export default connect(mapStateToProps)(Routes);
const styles = ({
login_style_bar: {
backgroundColor: '#f6f6f6',
shadowColor: "#f7f7f7",
elevation: 0,
height: 50,
},
login_style_bar_detail: {
backgroundColor: 'transparent',
shadowColor: "#f7f7f7",
elevation: 0,
height: 50,
},
bell: {
width: 30,
height: 30,
justifyContent: 'center',
alignItems: 'center',
},
notification: {
width: 14,
height: 14,
borderRadius: 7,
backgroundColor: '#B22850',
start: 10,
top: -10,
justifyContent: 'center',
alignItems: 'center',
},
notification_text: {
color: '#fff',
fontSize: 9,
fontFamily: 'ISFMedium',
},
notification_box: {
width: 40,
height: 40,
right: 20,
justifyContent: 'center',
alignItems: 'center',
},
bell: {
width: 30,
height: 30,
justifyContent: 'center',
alignItems: 'center',
},
notification: {
width: 14,
height: 14,
borderRadius: 7,
backgroundColor: '#B22850',
start: 10,
top: -10,
justifyContent: 'center',
alignItems: 'center',
},
notification_text: {
color: '#fff',
fontSize: 9,
fontFamily: 'ISFMedium',
},
})

How to set maxWidth in mobile screen?

I am trying to render few buttons in a row, but having some problem with css style. how can i set maxwidth in mobile screen? this is screen short of my problem
I want to set a css style when maxwidth are over then rest of the button are show in a new row automatically is its possible to render in react-native???
My source code::
import React from 'react';
import { View, Text, StyleSheet, TouchableHighlight } from 'react-native';
import { Header, Icon } from 'react-native-elements';
class Extras extends React.Component {
constructor(props){
super(props);
this.state = { selectFurnish: '', selectVeg: '', selectOtherFecility: '' };
this.onButtonPress = this.onButtonPress.bind(this);
}
leftComponent = () => {
return <Icon name='angle-left' color='#fff' type='font-awesome' onPress={() => {this.props.navigation.navigate('pricing')}} />
}
onButtonPress = (stateName, selected) =>{
const obj = Object.assign({},this.state);
obj[stateName] = selected;
this.setState( obj );
}
render() {
const furnish_button_props = [
{ id: 0, value: 'Full'},
{ id: 1, value: 'Semi'},
{ id: 2, value: 'None'}
];
const veg_button_props = [
{ id: 0, value: 'Yes'},
{ id: 1, value: 'No'}
];
const otherFacilities_button_props = [
{ id: 0, value: 'Parking'},
{ id: 1, value: 'Lift'},
{ id: 2, value: 'Gas Pipeline'},
{ id: 3, value: 'Pool'}
];
return(
<View style={styles.container}>
<Header
leftComponent={this.leftComponent()}
centerComponent={{text: 'NEW LISTING', style: {color: '#FFF', fontSize: 16}}}
outerContainerStyles={{backgroundColor: '#3498db'}}
/>
<View style={styles.block}>
<View>
<Text style={styles.textType}>Furnishing</Text>
<View style={{flexDirection: 'row'}}>
{furnish_button_props.map(i => {
return(
<TouchableHighlight
activeOpacity={1}
onPress={() => this.onButtonPress('selectFurnish',i.value)}
key={i.id}
style={ this.state.selectFurnish === i.value ? styles.buttonOnPress : styles.button }
>
<Text style={ this.state.selectFurnish === i.value ? styles.textOnPress : styles.text }>{i.value}</Text>
</TouchableHighlight>
)
})}
</View>
</View>
<View style={{marginTop: 50}}>
<Text style={styles.textType}>Vegetarian</Text>
<View style={{flexDirection: 'row'}}>
{veg_button_props.map(i => {
return(
<TouchableHighlight
activeOpacity={1}
onPress={() => this.onButtonPress('selectVeg', i.value)}
key={i.id}
style={ this.state.selectVeg === i.value ? styles.buttonOnPress : styles.button }
>
<Text style={ this.state.selectVeg === i.value ? styles.textOnPress : styles.text }>{i.value}</Text>
</TouchableHighlight>
)
})}
</View>
</View>
<View style={{marginTop: 50}}>
<Text style={styles.textType}>Other Facilities</Text>
<View style={{flexDirection: 'row'}}>
{otherFacilities_button_props.map(i => {
return(
<TouchableHighlight
activeOpacity={1}
onPress={() => this.onButtonPress('selectOtherFecility', i.value)}
key={i.id}
style={ this.state.selectOtherFecility === i.value ? styles.buttonOnPress : styles.button }
>
<Text style={ this.state.selectOtherFecility === i.value ? styles.textOnPress : styles.text }>{i.value}</Text>
</TouchableHighlight>
)
})}
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
maxWidth: '100%'
},
block: {
marginTop: 120,
marginLeft: 10
},
textType: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 5,
marginLeft: 5
},
button: {
borderColor: '#3498db',
borderWidth: 1,
borderRadius: 25,
width: 100,
height: 50,
marginLeft: 5,
marginRight: 5,
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},
buttonOnPress: {
borderColor: '#3498db',
backgroundColor: '#3498db',
borderWidth: 1,
borderRadius: 25,
width: 100,
height: 35,
marginLeft: 5,
marginRight: 5
},
text: {
fontSize: 14,
color: '#3498db'
},
textOnPress: {
fontSize: 14,
fontWeight: 'bold',
color: '#ffffff'
},
});
export default Extras;
You can add: flexWrap: 'wrap' to your view (<View style={{flexDirection: 'row'}}>)
More about flex

Resources