react native scrollview not scrolling on android - android

I have the following component:
export default class StoreComponent extends Component {
render() {
return (
<View style={styles.container}>
<ScrollView contentContainerStyle={styles.scroll}>
<StoreCarouselComponent />
<StoreDiscountComponent />
<StoreDetailsComponent />
</ScrollView>
</View>
);
}
}
with this style
import { StyleSheet, Dimensions, } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
scroll: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center'
},
image: {
width: Dimensions.get('window').width,
height: 350,
},
box: {
width: Dimensions.get('window').width - 30,
position: 'absolute',
shadowColor: '#000000',
shadowOpacity: 0.34,
shadowRadius: 5,
shadowOffset: {
width: 0,
height: 10
},
elevation: 10,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
borderColor: 'lightgrey',
backgroundColor: '#ffffff',
padding: 10,
marginTop: 410,
},
boxDiscount: {
width: Dimensions.get('window').width - 30,
position: 'absolute',
shadowColor: '#000000',
shadowOpacity: 0.34,
shadowRadius: 5,
shadowOffset: {
width: 0,
height: 10
},
elevation: 10,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
borderColor: 'lightgrey',
backgroundColor: '#253241',
padding: 10,
marginTop: 320,
},
title: {
fontSize: 30
},
distance: {
fontSize: 20,
color: '#767676'
},
distanceElement: {
fontSize: 20,
color: '#44D9E6'
},
address: {
fontSize: 20,
color: '#767676'
},
category: {
fontSize: 20,
color: '#767676',
},
categoryElement: {
fontSize: 20,
color: '#44D9E6',
},
hr: {
borderBottomColor: 'lightgrey',
borderBottomWidth: 1,
},
icons: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
}
});
export default styles;
my scrollview works on ios but on android don't and I don't understand why
here a an image of the app and as you can see I need to scroll on android:

try to import from
import { ScrollView } from 'react-native-gesture-handler';
instead of from
'react native'

Use flexGrow : 1 inside your styles.scroll instead of flex:1

use flex: 1 inside style={styles.container} and delete it from .scroll

I had a similar issue. The culprit turned out to be contentContainerStyle={{flex: 1}} on my ScrollView. Removing that (It turned out to be unnecessary, anyway.) fixed the problem on Android.

the styles on your scroll contentContainerStyle is uneccessary
try to remove : styles.scroll
and just give padding or margin on component if you to center it
if its row add props horizontal = true on ScrollView.

I too had the similar structure as mentioned in question. I had 3 direct children View inside ScrollView and it wasn't scrolling. I tried all above solutions with flex, flexGrow etc. Nothing worked for me.
What worked for me is wrapping all 3 direct children to another View, so for ScrollView there's only one direct children.
// THIS DOES NOT SCROLL
<ScrollView>
<View>// 1st direct children</View>
<View>// 2nd direct children</View>
<View>// 3rd direct children</View>
</ScrollView>
// THIS WILL SCROLL, As now ScrollView has only one direct children
<ScrollView>
<View>
<View>// 1st children</View>
<View>// 2nd children</View>
<View>// 3rd children</View>
</View>
</ScrollView>

Related

Vertical scrolling on React Native Dropdowns

My Android app built using React Native doesn't allow one to scroll a DropDownPicker (github.com/hossein-zare/react-native-dropdown-picker). What can be changed in the below code to fix this? The parent components and relevant styles can be found below. The code itself is also wrapped in a flex 1 container view.
<View style = {styles.dropdownContainerIn}>
<TextInput
keyboardType = "number-pad"
style = {styles.toAmount}
placeholder="Amount"
placeholderTextColor="white"
value = {text}
editable = {false}
maxLength = {18}
/>
<DropDownPicker
placeholder={from}
open={openFrom}
items={baseCurrencies}
setOpen={setOpenFrom}
onOpen={() => setOpenTo(false)}
setItems={setBases}
onSelectItem={(from) => {setFrom(from.label)}}
style={styles.dropdown}
textStyle={styles.dropdownText}
dropDownContainerStyle={styles.dropdownOption}
searchable = {true}
searchPlaceholder="Search"
/>
</View>
dropdown:{
backgroundColor: "transparent",
borderColor: 'white',
borderWidth: 3,
width: 120,
height: 60,
borderRadius: 3,
flex: 1
},
dropdownText:{
fontSize: 15,
fontWeight: 'bold',
color: 'white',
},
dropdownOption:{
backgroundColor: '#123',
borderColor: 'white',
borderWidth: 2,
width: 340,
transform: [{translateX: -220}],
},
dropdownContainerIn:{
flexDirection: 'row',
transform: [{translateX: 140}, {translateY: 160}],
marginRight: 20,
},
toAmount:{
width: 220,
height: 60,
borderColor: 'white',
borderWidth: 3,
borderRadiusLeft: 3,
borderRightWidth: 0,
color: 'white',
fontSize: 20,
paddingLeft: 15,
},
For those encountering this issue add this line of code underneath the import statements: DropDownPicker.setListMode("MODAL")

(React-Native) Item in Flatlist do not shows the correct style as in Stylesheet on the first load

I am trying to create a view with a top card showing an image and a bottom card showing relative information in a horizontal flatlist.
The style gets broken on the first load and as soon as I refresh the code without any change, the component shows the correct style as expected.
This is happening after I migrated the react native from 0.60.5 to 0.61.0.
This is the code for component.
<View
accessible={Platform.OS === 'ios' ? false : true}
style={styles.container}>
<View style={styles.itemContainer}>
<View style={styles.topContainer}>
<ImageBackground
source={{uri: item.img, cache: 'default'}}
resizeMode="contain"
imageStyle={{borderRadius: 4}}
style={styles.topContainer}>
</ImageBackground>
<View style={styles.bottomContainer}>
<Text style={styles.destination}>{item.title}</Text>
<Text style={styles.subtitle}>{item.description}</Text>
</View>
</View>
</View>
</View>
This is the stylesheet.
import {StyleSheet, Platform} from 'react-native';
import Color from '../../../../utilities/Color';
import {BaseStyle} from '../../../../utilities/Style';
const flex1 = {
flex: 1,
};
const flexRow = {
flexDirection: 'row',
};
const centerView = {
justifyContent: 'center',
alignItems: 'center',
};
const cardStyle = {
...Platform.select({
ios: {
borderWidth: 1,
borderColor: Color.white,
shadowOffset: {width: 1, height: 1},
shadowOpacity: 0.2,
shadowRadius: 2,
borderRadius: 2,
shadowColor: 'rgba(0, 0, 0, 1.0)',
},
android: {
elevation: 2,
borderRadius: 2,
},
}),
};
export default StyleSheet.create({
container: {
...flex1,
padding: 16,
borderBottomWidth: 1,
borderColor: '#efefef',
},
title: {
...BaseStyle.font16RobotoBoldGray,
},
subtitle: {
...BaseStyle.textSubHead1,
top: 10,
marginRight: 10,
color: Color.lightTextGray,
},
});
export const ItemStyle = StyleSheet.create({
container: {
...flex1,
marginBottom: 15,
},
itemContainer: {
height: 210,
width: 260,
marginRight: 15,
},
topContainer: {
height: 162,
borderRadius: 4,
},
bottomContainer: {
...cardStyle,
position: 'absolute',
left: 0,
right: 0,
top: 120,
marginHorizontal: 8,
paddingHorizontal: 15,
paddingVertical: 12,
borderRadius: 4,
backgroundColor: Color.white,
},
destination: {
...BaseStyle.textTitle,
fontSize: 14,
lineHeight: 18,
color: Color.darkGray,
marginBottom: 8,
},
subHeading: {
marginBottom: 4,
},
caption: {
...BaseStyle.textCaption,
color: Color.lightTextGray,
},
subtitle: {
...BaseStyle.textSubHead1,
},
});
This is the image at the first load
This is the image after I refresh the code.
Please suggest a way, how can I debug it. Or something wrong I am doing in my stylesheet?
Removing all the borderRadius solved it.

Why isn't my box shadow showing on Android?

I'm quite new to React Native and React in general, and I'm stuck on this particular problem:
I followed some tutorials and other answers on other posts there on StackOverflow, but I can't manage to see the border Shadow I set on these "cards". The shadow isn't displayed on my phone.
I hope so of you old wizards of the internet can help me find a solution to this problem, I'd be really grateful.
export class Boss extends Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
hp: props.hp,
ap: props.ap,
};
}
render(){
return(
<View style={styles.cardContainer}>
<View style={[styles.cardBackground , this.state.hp > 0 ?
{ backgroundColor: 'gold' }
: { backgroundColor: 'red' }]}>
<View style={styles.cardFrame}>
<Text style={styles.cardName}>{this.props.name}</Text>
<View style={styles.bossLifeWrapper}>
<Button title={'+'} onPress={this.incrementeHP}></Button>
<Text style={styles.bossHP}>{this.state.hp}</Text>
<Button title={'-'} onPress={this.decrementeHP}></Button>
</View>
<Text style={styles.bossAP}>{this.state.ap}</Text>
<Text style={styles.bossPowerLabel}>{this.props.passive}</Text>
<View style={styles.cardTextBox}>
<Text style={styles.bossPowerLabel}>Pouvoir: {this.props.powerLabel}</Text>
<Text style={styles.bossEnrageLabel}>Enrage: {this.props.enrageLabel}</Text>
</View>
</View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
cardContainer: {
width: '80%',
height: 450,
backgroundColor: "#171314",
alignItems:"center",
borderStyle: "solid",
borderColor: "black",
borderWidth: 1,
margin: '10%',
borderRadius: 10,
padding: 10,
shadowColor: "white",
shadowOffset: {
width: 0,
height: 8,
},
shadowOpacity: 0.44,
shadowRadius: 10.32,
elevation: 16,
},
cardBackground: {
backgroundColor: '#171314',
borderRadius: 5,
padding: 10,
zIndex: 0
},
cardFrame: {
zIndex: 1,
position: 'relative',
height: '98%',
maxWidth: '97%',
left: '1%',
top: '0.5%',
display: 'flex',
flexDirection: 'column',
backgroundColor: 'white'
},
cardName: {
flex: 1,
backgroundColor: 'red',
alignItems:"center",
borderStyle: "solid",
borderBottomColor: "grey",
borderBottomWidth: 5,
margin: 5,
marginHorizontal: 5,
fontSize: 20,
height: 10
},
bossHP: {
width: '100%',
color: 'blue'
},
bossAP: {
width: '100%',
color: 'red'
},
bossLifeWrapper: {
flex: 1,
flexDirection: "column"
},
});
have you tried elevate in box styles? ex: elevate:10,

React native keyboard's height changes entire view

My layout with two inputs and a button works well without the keyboard. But as soon as I clicked the input box the keyboard appears and changes the height of the screen. Then things align wrong . I already tried using keyboard avoiding view. But the error is still there.
import {
StyleSheet,
Text,
View,
TextInput,
Button,
KeyboardAvoidingView,
} from 'react-native';
import { Formik} from 'formik';
import React, { Component } from 'react';
class Demo extends Component {
render(){
return (
<KeyboardAvoidingView style={styles.container} behavior= "position , padding , height">
<View style={styles.container}>
<Text style={styles.titleText}>Profile settings</Text>
<View style={styles.card}>
<Formik
initialValues={{
name: '',
mobile: '',
}}
onSubmit={(values) => {
console.log(JSON.stringify(values));
}}>
{(props) => (
<View>
<TextInput
placeholder={'name'}
onChangeText={props.handleChange('name')}
value={props.values.name}
style={styles.cardTextSmall}
/>
<TextInput
placeholder={'email'}
onChangeText={props.handleChange('mobile')}
value={props.values.mobile}
style={styles.cardTextSmall}
/>
<Button
title={'submit'}
/>
</View>
)}
</Formik>
<View style={styles.centerButton}></View>
</View>
</View>
</KeyboardAvoidingView>
);
};
}
const styles = StyleSheet.create({
centerButton: {
top: '1%',
alignContent: 'center',
alignItems: 'center',
},
titleText: {
fontFamily: 'Segoe UI',
fontSize: 30,
position: 'relative',
left: '7%',
top: 72,
},
cardContent: {
paddingHorizontal: '10%',
marginHorizontal: 10,
},
cardTextLarge: {
paddingTop: '15%',
fontSize: 18,
color: '#A6A6A6',
fontFamily: 'Segoe UI',
},
cardTextSmall: {
borderBottomColor: 'black',
borderBottomWidth: 1,
fontFamily: 'Segoe UI',
fontSize: 18,
color: '#404040',
},
cardTextModule: {
paddingLeft: '15%',
paddingTop: '2%',
fontFamily: 'Segoe UI',
fontSize: 18,
width: '100%',
color: '#404040',
},
card: {
borderRadius: 6,
backgroundColor: 'red',
shadowOpacity: 0.3,
shadowOffset: {width: 1, height: 1},
marginHorizontal: 4,
left: '6.5%',
top: '19%',
height: '78%',
width: '85%',
margin: 'auto',
position: 'relative',
zIndex: -1,
},
});
export default Demo;
I'm a beginner here. If you could please give me some explanation. thanks!
This is happening because you have used KeyboardAvoidingView with one of the behavior as padding. So whenever you click on TextInput it adds bottom padding to the view and view moves towards the top.
If you don't want it to happen, use View tag instead of KeyboardAvoidingView.

How can I set elevation shadow only on the bottom on react native?

I'm trying to add a shadow on the bottom of a view, but I don't how to do it on Android. With elevation it put a shadow also on the top. Is there a way to do it like on iOS?
Here's my code:
export function makeElevation(elevation) {
const iosShadowElevation = {
shadowOpacity: 0.0015 * elevation + 0.18,
shadowRadius: 0.5 * elevation,
shadowOffset: {
height: 0.6 * elevation,
},
};
const androidShadowElevation = {
elevation,
};
return Platform.OS === 'ios' ? iosShadowElevation : androidShadowElevation;
}
left: iOS (expected)
right: Android
EDIT: The only "fake" solution I found is to use react-native-linear-gradient instead to create a custom shadow.
You can use overflow: 'hidden' to achieve the desired result without having to install a library.
wrap the view in a parent view and set the parent's overflow to hidden and apply a padding only on the side where you want your shadow to appear like so:
<View style={{ overflow: 'hidden', paddingBottom: 5 }}>
<View
style={{
backgroundColor: '#fff',
width: 300,
height: 60,
shadowColor: '#000',
shadowOffset: { width: 1, height: 1 },
shadowOpacity: 0.4,
shadowRadius: 3,
elevation: 5,
}}
/>
</View>
result:
here's a custom component that you can use:
import React from 'react'
import { View, StyleSheet, ViewPropTypes } from 'react-native'
import PropTypes from 'prop-types'
const SingleSidedShadowBox = ({ children, style }) => (
<View style={[ styles.container, style ]}>
{ children }
</View>
);
const styles = StyleSheet.create({
container:{
overflow: 'hidden',
paddingBottom: 5,
}
});
SingleSidedShadowBox.propTypes = {
children: PropTypes.element,
style: ViewPropTypes.style,
};
export default SingleSidedShadowBox;
example:
<SingleSidedShadowBox style={{width: '90%', height: 40}}>
<View style={{
backgroundColor: '#fff',
width: '100%',
height: '100%',
shadowColor: '#000',
shadowOffset: { width: 1, height: 1 },
shadowOpacity: 0.4,
shadowRadius: 3,
elevation: 5,
}} />
</SingleSidedShadowBox>
you can adjust the padding depending on your shadow
Unfortunately RN don't support it by default, check blow link
https://ethercreative.github.io/react-native-shadow-generator/
but you can use npm packages like this
Answers above are quite helpful but the workaround that worked best for me is by wrapping both, 1-The component dropping the shadow and 2-The component the shadow is being dropped on in a component with the style rule overflow: "hidden"
Example:
function SomeScreen (){
return (
<View style={{overflow: "hidden"}}/*Top shadow is hidden*/>
<NavBar style={styles.shadow}/*The component dropping a shadow*/ />
<ProductList /*The component under the shadow*/ />
</View>
);
}
const styles = StyleSheet.create({
shadow: {
shadowColor: "black",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 6,
shadowOpacity: 0.2,
elevation: 3,
}
});
Just append/put this to main view container:
const styles = StyleSheet.create({
container: {
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: {width: 1, height: 3},
shadowOpacity: 0.4,
},
android: {
elevation: 4,
},
}),
},
});

Categories

Resources