React Native scroll view not showing - android

I have a scroll view at the top level of the view hierarchy. I'm trying to get it to show its content but I haven't had any luck.
I see that the documentation says scroll views need a bounded height to work. I can't seem to get it to have a bounded height. This is what I have so far.
'use strict';
const React = require('react-native');
const {
StyleSheet,
Text,
View,
BackAndroid,
TextInput,
TouchableNativeFeedback,
ScrollView
} = React;
const ActionButton = require('./action-button'),
Dimensions = require('Dimensions');
module.exports = React.createClass({
handleBackButtonPress () {
if (this.props.navigator) {
this.props.navigator.pop();
return true;
}
return false;
},
componentWillMount () {
BackAndroid.addEventListener('hardwareBackPress', this.handleBackButtonPress);
},
componentWillUnmount () {
BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButtonPress);
},
onInputFocus (refName) {
setTimeout(() => {
let scrollResponder = this.refs.getScrollResponder();
scrollResponder.scrollNativeHandleToKeyboard(
React.findNodeHandle(this.refs[refName]),
110,
true
);
}, 50);
},
render: function() {
return (
<View style={styles.scrollWrapper}>
<ScrollView ref='scrollView' style={styles.scroller}>
<View style={styles.container}>
<View style={styles.header}>
<Text>New Post</Text>
<View style={styles.actions}>
<ActionButton handler={this.handleBackButtonPress} icon={'fontawesome|close'}
size={15} width={15} height={15} />
</View>
</View>
<View style={styles.content}>
<TextInput underlineColorAndroid={'white'}
placeholder={'Who\'s your professor?'}
ref='professor'
onFocus={this.onInputFocus.bind(this, 'professor')}
/>
<TextInput multiline={true}
underlineColorAndroid={'white'}
placeholder={'What do you think?'}
ref='post'
onFocus={this.onInputFocus.bind(this, 'post')}
/>
</View>
<View style={styles.footer}>
<TouchableNativeFeedback
background={TouchableNativeFeedback.SelectableBackground()}>
<View style={{width: 50, height: 25, backgroundColor: 'green'}}>
<Text>Submit</Text>
</View>
</TouchableNativeFeedback>
</View>
</View>
</ScrollView>
</View>
);
}
});
const styles = StyleSheet.create({
scrollWrapper: {
flex: 1
},
scroller: {
flex: 1
},
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
backgroundColor: 'white',
padding: 5,
},
post: {
flex: 1,
},
actions: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignSelf: 'center'
},
header: {
flex: 1,
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: 35,
padding: 5,
flexDirection: 'row'
},
content: {
flex: 1,
position: 'absolute',
top: 35
},
footer: {
flex: 1,
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: 35
}
});
EDIT: So I changed the background colors of all the components to something obvious. I was able to simplify the view, so now the ScrollView is the root of the component. The container view (the immediate child of the ScrollView) is the one who isn't filling all the available space. I'm still playing around with it but any help is much appreciated.

To fix this, you need to set flex: 1 to the parent's view. Then, for ScrollView, use contentContainerStyle={{flexGrow: 1}} rather than using style.
<View style={{flex: 1}}>
<ScrollView contentContainerStyle={{flexGrow: 1}}>
...
</ScrollView>
</View>

If you are using position: absolute, you need to specify a left:0, right:0 for it to work with your current setup, though I am not entirely sure position: absolute is needed at all. Try this:
content: {
flex: 1,
position: 'absolute',
top: 35,
left:0,
right:0,
bottom:0
},

Try setting removeClippedSubviews={false} as a property of and see what happens.

Related

How do I make my FlatList scrollable while sibling Modal is visible?

My FlatList is not scrollable while my Modal is visible. I've tried a bunch of things but none seem to do the job. I'm building for Android. You can find the Expo snack here https://snack.expo.dev/#ordis45/modal_flatlist?platform=android. Code is as follows:
Any pointers in the right direction would be appreciated!
const styles = StyleSheet.create({
container: {
flex: 1,
},
modal: {
position: 'relative',
bottom: 0,
height: 20,
},
modalContent: {
backgroundColor: 'white',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'rgba(0, 0, 0, 0.1)',
},
openButton: {
backgroundColor: '#F194FF',
borderRadius: 20,
padding: 10,
elevation: 2,
position: 'absolute',
bottom: 20,
right: 20,
},
});
const myComp = () => {
const [modalVisible, setModalVisible] = useState(false);
return (
<View style={styles.container} overflow='scroll'>
<Modal
visible={modalVisible}
style={styles.modal}
transparent={true}
>
<View style={styles.modalContent}>
<Text>This is a modal</Text>
<TouchableOpacity onPress={() => setModalVisible(false)}>
<Text>Close</Text>
</TouchableOpacity>
</View>
</Modal>
<FlatList
style={{height: 300, position: 'relative', elevation: 1}}
data={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
renderItem={({ item }) => <Text style={{padding: 50}}>{item}</Text>}
/>
<TouchableOpacity onPress={() => setModalVisible(true)} style={styles.openButton}>
<Text>Open</Text>
</TouchableOpacity>
</View>
);
};
I tried things like changing the elevation and z-indices of the View component and the FlatList and Modal components- to no avail. I also tried setting supportedOrientations={['landscape']} but that didn't work either.

React Native Vertical Delivery Progress Bar

How can I put a Vertical progress bar on React Native
I need to make a delivery bar progress
**Example: driver is at point A and needs to go to point B ...*
This is a bit tricky but do able. You will have to have a vertical line and place the items horizontally in a row format.
Lets say you have a data structure like this.You can update the current location using the flag and set the labels.
const data = [
{ title: 'Stop 1', letter: 'A', isCurrent: false },
{ title: 'Stop 2', letter: 'B', isCurrent: false },
{ title: 'Stop 3', letter: 'C', isCurrent: false },
{ title: 'Stop 4', letter: 'D', isCurrent: true },
{ title: 'Stop 5', letter: 'E', isCurrent: false },
];
This will be your component which handle the map
const MapProgress = (props) => {
if (!props.data || props.data.lenght === 0) return null;
const firstItem = props.data.shift();
return (
<View style={{ flex: 1 }}>
<View style={styles.verticalLine}></View>
<View style={styles.verticalWrap}>
<View style={styles.itemWrap}>
<View style={styles.firstPoint}></View>
<View style={{ marginLeft: 5, flex: 1 }}>
<Text>{firstItem.title}</Text>
</View>
</View>
{props.data.map((item) => (
<View style={styles.itemWrap}>
<View style={styles.pointWrap}>
<Text
style={[
styles.markerText,
item.isCurrent ? styles.currentMarker : null,
]}>
{item.letter}
</Text>
</View>
<View style={{ marginLeft: 5, flex: 1 }}>
<Text style={item.isCurrent ? styles.currentMarker : null}>
{item.title}
</Text>
</View>
</View>
))}
</View>
</View>
);
};
These will have to be styled to place the views properly
const styles = StyleSheet.create({
verticalLine: {
backgroundColor: 'black',
width: 2,
height: '95%',
position: 'absolute',
marginLeft: 35,
marginTop: 20,
},
verticalWrap: {
justifyContent: 'space-between',
height: '100%',
},
itemWrap: {
width: 200,
height: 40,
borderWidth: 1,
marginLeft: 20,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
},
pointWrap: {
backgroundColor: 'black',
height: 20,
width: 20,
marginLeft: 5,
alignItems: 'center',
},
firstPoint: {
backgroundColor: 'black',
borderRadius: 20,
height: 10,
width: 10,
marginLeft: 10,
},
markerText: { color: 'white' },
currentMarker: { color: 'green' },
});
You can use the component like this
<MapProgress data={data} />
You can tryout the snack below
https://snack.expo.io/#guruparan/mapprogress
You better try this lib: https://github.com/oblador/react-native-progress#progressbar
Or you can create a your custom progressbar, it pretty simple in React Native. You could try
<View style={{height: 50, width: '100%', flexDirection: 'row'}}>
<View style={{height: '100%', flex: this.state.currentProgress, backgroundColor: "blue"}}/>
<View style={{height: '100%', flex: 100 - this.state.currentProgress, backgroundColor: "grey"}}/>
</View>
I think that it.
For vertical progress bar. You cane use
react-native-progress npm and simply rotate the bar using style transform property.
import React from 'react';
import * as Progress from 'react-native-progress';
return <Progress progress={progress} style={{ transform: [{ rotate: '-90deg' }] }} />;
Please refer original answer:
https://github.com/oblador/react-native-progress/issues/61#issuecomment-322694271

Add "radius" to bottom side of image

This is design that I want to implement for my mobile application:
And this is what is currently accomplished to implement:
Implemented design
As you can see folowing some online examples i manage to curve the picture but its curved on both ends instead of just on the bottom.
This is my style code:
const mainStyle = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
backgroundColor: "#d3c586",
alignItems: "center",
justifyContent: "space-between",
},
cardContainer: {
flex: 1,
alignSelf: "center",
backgroundColor: "#d3c586",
alignItems: "center",
justifyContent: "space-between",
overflow: "hidden",
},
cardImageContainer: {
flex: 0.6,
borderRadius: width,
width: width,
height: width,
bottom: 0,
overflow: 'hidden',
},
cardImage: {
height: height / 2,
width: width,
bottom: 0,
marginLeft: 0,
}};
This is a list of items that can be swiped and i render it from this function:
renderItem ({item, index}) {
return (
<View style={mainStyle.cardContainer}>
<View style={mainStyle.cardImageContainer}>
<TouchableOpacity onPress={(event) => this.handleDoubleTap(item)} onLongPress={(event) => this.handlePictureShare(item)}>
<LoadImage style={mainStyle.cardImage} source={{uri: item.url}} thumbnailSource={{uri: item.url}}/>
</TouchableOpacity>
</View>
<View style={mainStyle.cardTextContainer}>
<Text numberOfLines={25} style={{fontSize: 19}}>{item.fact}</Text>
</View>
</View>
)
}
I do not have a lot of experience with CSS since most of my work is on the backend.
Check these links BorderBottomLeftRadius BorderBottomRightRadius
This way you can only give radius bottom of your image.
You can try like this:
import React, { Component } from 'react';
import { View } from 'react-native';
export default class FlexDirectionBasics extends Component {
render() {
return (
// Try setting `flexDirection` to `column`.
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}}>
<View style={{width: 100, height: 100, backgroundColor: 'steelblue', borderBottomColor: 'black', borderBottomEndRadius: 10, borderBottomStartRadius: 10 }} />
</View>
);
}
}

React Native v0.42 flexbox error in ScrollView

My React Native render code is:
<ScrollView
contentContainerStyle={{
minHeight: 100,
flexDirection: "column",
alignItems: "stretch",
marginTop: 16,
}}
alwaysBounceVertical={false}
showsVerticalScrollIndicator={false}
>
<View style={{flex: 0.5, backgroundColor: "green"}}>
<View style={{height: 10, backgroundColor: "yellow"}}/>
</View>
<View style={{flex: 0.5, backgroundColor: "blue"}}/>
</ScrollView>
The code above should render 2 views, of height 50 each, top one green and bottom one yellow. Inside the top view, there should be a yellow view of height 10.
Instead, it renders the top view with height 60 and bottom box with height 50. The top box has a box inside with height 10. The colours are all correct.
However, if I change the height:10 part to height:"20%", it works all fine.
How can I solve this problem?
Thanks.
You could either position your yellow view absolutely:
<ScrollView
contentContainerStyle={{
minHeight: 100,
flexDirection: "column",
alignItems: "stretch",
marginTop: 16,
}}
alwaysBounceVertical={false}
showsVerticalScrollIndicator={false}
>
<View style={{flex: 0.5, backgroundColor: "green"}}>
<View style={{
height: 10,
backgroundColor: "yellow",
position: 'absolute',
top: 0, left: 0, right: 0
}}/>
</View>
<View style={{flex: 0.5, backgroundColor: "blue"}}/>
</ScrollView>
or use a fixed height on the ScrollView:
<ScrollView
contentContainerStyle={{
height: 100,
flexDirection: "column",
alignItems: "stretch",
marginTop: 16,
}}
alwaysBounceVertical={false}
showsVerticalScrollIndicator={false}
>
The solution to this problem is to wrap the "green" view in a component like (I am using typescript):
class VerticalScrollingContentContainer extends
React.PureComponent<{style?: Styles},
{mainViewHeight: number, isMeasured: boolean}> {
constructor(props: any) {
super(props);
this.state = {
mainViewHeight: 0,
isMeasured: false,
};
}
layoutReceived = (width: number, height: number) => {
let newHeight = height > width ? height : width;
this.setState(
oldState => ({mainViewHeight: newHeight, isMeasured: true})
);
}
render() {
let isMeasured = this.state.isMeasured;
let mainViewHeight = this.state.mainViewHeight;
let innerContainerLayout = {
flexDirection: "column",
};
if (!isMeasured) {
innerContainerLayout = {
...innerContainerLayout,
flex: 1
};
} else {
innerContainerLayout = {
...innerContainerLayout,
minHeight: mainViewHeight
};
}
return (
<ScrollView
style={{flex: 1}}
contentContainerStyle={innerContainerLayout as any}
alwaysBounceVertical={false}
showsVerticalScrollIndicator={false}>
<View
style={[
{
flexGrow: 1,
alignItems: "flex-start",
flexDirection: "column",
},
this.props.style
]}
onLayout={(e) => {
this.layoutReceived(e.nativeEvent.layout.width, e.nativeEvent.layout.height); }}>
{this.props.children}
</View>
</ScrollView>
);
}
}

React native flex box not using all available space

I have a layout that I want to make full screen. This is how it looks right now:
What I want is for the layout to take up all the space on the screen (so the submit button should be way down at the bottom). I'm trying to use {flex: 1} but it's not working. Here's the code:
'use strict';
const React = require('react-native');
const {
StyleSheet,
Text,
View,
BackAndroid,
TextInput,
TouchableNativeFeedback,
ScrollView
} = React;
const ActionButton = require('./action-button');
module.exports = React.createClass({
handleBackButtonPress () {
if (this.props.navigator) {
this.props.navigator.pop();
return true;
}
return false;
},
componentWillMount () {
BackAndroid.addEventListener('hardwareBackPress', this.handleBackButtonPress);
},
componentWillUnmount () {
BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButtonPress);
},
onInputFocus (refName) {
setTimeout(() => {
let scrollResponder = this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(this.refs[refName]),
0,
true
);
}, 50);
},
render: function() {
return (
<ScrollView ref='scrollView' style={styles.scroller}>
<View style={styles.container}>
<View style={styles.header}>
<Text>New Post</Text>
<View style={styles.actions}>
<ActionButton handler={this.handleBackButtonPress} icon={'fontawesome|close'}
size={15} width={15} height={15} />
</View>
</View>
<View style={styles.content}>
<TextInput underlineColorAndroid={'white'}
placeholder={'Who\'s your professor?'}
ref='professor'
onFocus={this.onInputFocus.bind(this, 'professor')}
style={styles.professor}
/>
<TextInput multiline={true}
underlineColorAndroid={'white'}
placeholder={'What do you think?'}
ref='post'
onFocus={this.onInputFocus.bind(this, 'post')}
style={styles.post}
/>
</View>
<View style={styles.footer}>
<TouchableNativeFeedback
background={TouchableNativeFeedback.SelectableBackground()}>
<View style={{width: 50, height: 25, backgroundColor: 'green'}}>
<Text>Submit</Text>
</View>
</TouchableNativeFeedback>
</View>
</View>
</ScrollView>
);
}
});
const styles = StyleSheet.create({
scroller: {
flex: 1,
flexDirection: 'column'
},
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
backgroundColor: 'white',
padding: 5,
},
post: {
flex: 3
},
professor: {
flex: 1
},
actions: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignSelf: 'center'
},
header: {
flex: 1,
padding: 5,
flexDirection: 'row'
},
content: {
flex: 4
},
footer: {
flex: 1
}
});
From what I can see, I'm setting the flex property all the way down the view hierarchy but that still isn't doing anything (at the top level is a Navigator with {flex: 1} as well). Any suggestions?
What you want is the contentContainerStyle prop of the ScrollView component. If you replace :
<ScrollView ref='scrollView' style={styles.scroller}>
with :
<ScrollView ref='scrollView' contentContainerStyle={styles.scroller}>
That will fix your problem.
As stated in the doc :
These styles will be applied to the scroll view content container which wraps all of the child views.
Hope it helps!
If the colors are accurate in the screenshot, your scrollview is taking up all the vertical space already but the container is not (container background color is white). This is illustrating how scrollviews work. They act as containers where flex can't really grow the children to fit the vertical space as it is potentially infinite. Instead the children are rendered at their natural height. http://devdocs.io/react_native/scrollview
try instead using a view that takes up the entire screen height.
<View style={styles.container}>
... components here ...
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between'
}
})
You need to set a flexDirection: 'row' property for the outermost container:
scroller: {
flex:1,
flexDirection: 'row'
}
I've set up a basic version of your app here. The rest of the code is pasted below for the full working example:
https://rnplay.org/apps/gjBqgw
'use strict';
var React = require('react-native');
var {
StyleSheet,
Text,
View,
BackAndroid,
TextInput,
TouchableNativeFeedback,
ScrollView,
AppRegistry,
TouchableHighlight
} = React;
var SampleApp = React.createClass({
render: function() {
return (
<ScrollView ref='scrollView' style={styles.scroller}>
<View style={styles.container}>
<View style={styles.header}>
<Text>New Post</Text>
<View style={styles.actions}>
<TouchableHighlight handler={this.handleBackButtonPress} icon={'fontawesome|close'}
size={15} width={15} height={15}>
<Text>Button Text</Text>
</TouchableHighlight>
</View>
</View>
<View style={styles.content}>
<Text>Hello from content</Text>
</View>
<View style={styles.footer}>
<TouchableHighlight>
<View style={{width: 50, height: 25, backgroundColor: 'green'}}>
<Text>Submit</Text>
</View>
</TouchableHighlight>
</View>
</View>
</ScrollView>
);
}
});
const styles = StyleSheet.create({
scroller: {
flex:1,
flexDirection: 'row'
},
container: {
flex: 1,
backgroundColor: 'white',
padding: 5,
},
post: {
flex: 3
},
professor: {
flex: 1
},
actions: {
flex: 1,
flexDirection: 'row',
alignSelf: 'center'
},
header: {
flex: 1,
padding: 5,
flexDirection: 'row'
},
content: {
flex: 4
},
footer: {
flex: 1,
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);

Categories

Resources