ScrollView not Scrolling - ReactNative - android

I have the following ScrollView, but my attempt just won't scroll. I am not sure what am going about it wrong in my implementation. Hope you can help.
Thank you all in advance.
class RecentMediaUploadsWidget extends Component {
renderImage = (imgURI) => {
return (
<TouchableOpacity>
<View>
<Image
style={styles.imageStyle}
source={{ uri: ("file:///" + imgURI) }}
/>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={styles.containerWrapper}>
<ScrollView>
<View style={styles.mainContainerStyle}>{this.props.itemsPaths.map(this.renderImage)}</View>
</ScrollView>
</View>
);
}
}
export default RecentMediaUploadsWidget;
And the styles is showing below
var styles = StyleSheet.create({
containerWrapper: {
flexDirection: 'column',
alignSelf: 'flex-start',
},
mainContainerStyle: {
flexDirection: 'row',
flex: 1,
},
imageStyle: {
width: imgWidth, height: imgWidth,
overflow: "hidden",
alignSelf: 'stretch',
},
})

instead of using style inside <ScrollView> use contentContainerStyle
eg:
<ScrollView
contentContainerStyle={{ flexGrow: 1, width: WIDTH, height: HEIGHT, justifyContent:
'space-between' }}
>

Related

justifyContent not applying in View React Native

For some reason in this view the justify Content tag does not apply in my view ? I have tried applying it in the modalScreen view but that does not work either. Any ideas ?
function BottomPopup() {
return (
<View style={styles.modalScreen}>
<View style={styles.topbar}>
<MaterialCommunityIcons name="arrow-left" size={24} color="black" />
<Text>Create Post</Text>
<MaterialCommunityIcons name="content-save" size={24} color="black" />
</View>
<View>
<Text>hey</Text>
<Text>hey</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
modalScreen: {
alignItems: "center",
},
topbar: {
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
},
});
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
const styles = StyleSheet.create({
modalScreen: {
flex:1,
alignItems: "center",
backgroundColor: "yellow",
},
topbar: {
width: width,
flexDirection: "row",
justifyContent: "space-around",
backgroundColor: "green",
},
});
Add flex:1 in modalScreen style like Snack.IO
I had to add width: "100%" and then it worked

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 - Can't increase width of Button in row

I tried both absolute and flex dimensions, the View just sets the Button at standard dimensions (approx 50px). The height is stretched, but the width can't possibly change.
class Calculator extends Component {
constructor() {
super();
this.state = { "lastClicked" : "None" };
this.buttonPress = this.buttonPress.bind(this);
}
createButton(id) {
return (
<Button
title={id}
onPress={() => this.buttonPress(id)}
/>
);
}
buttonPress(id) {
this.setState({ "lastClicked" : id });
}
render() {
return (
<View style={{alignContent: "stretch"}}>
<View style={{width: 500}}>
<Text style={{fontSize: 30}}>This is a JavaScript Calculator</Text>
<Text style={{fontSize: 20}}>You clicked: {this.state.lastClicked}</Text>
</View>
<View style={{width: 500}}>
<View style={{ width: 500, height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch"}}>
{this.createButton("4")}
{this.createButton("5")}
{this.createButton("6")}
</View>
<View style={{ width: 500, height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch"}}>
{this.createButton("4")}
{this.createButton("5")}
{this.createButton("6")}
</View>
<View style={{ width: 500, height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch"}}>
{this.createButton("1")}
{this.createButton("2")}
{this.createButton("3")}
</View>
</View>
</View>
);
}
}
}
Can you see the issue? I am new to React-Native and the issue already consumed 3 hours of my life.
You can replace the createButton() method with something like that:
createButton(id) {
return (
<TouchableWithoutFeedback onPress={() => this.buttonPress(id)}>
<View style={{flex: 3, flexDirection:'column', justifyContent:'center', alignItems:'center'}}>
<Text style={{fontSize:30}}>{id}</Text>
</View>
</TouchableWithoutFeedback>
);
}
I wrapped a <View> with style flex: 3 for setting the width to a third of the screen size. flexDirection:'column' and justifyContent:'center' will center the number in the middle of the View. The View is wrapped in a TouchableWithoutFeedback so that we can bind the onPress event.
For your grid of numbers, you wrapped then in <View style={{width: 500}}>. This is not always the size of the screen. It's easy to get the screen width using Dimensions.
At the start of your file, you can declare something like:
const screenWidth = Dimensions.get('window');
And then replace <View style={{width: 500}}> by <View style={{width: screenWidth}}>.
Overall, your new code should look like:
import React, { Component } from 'react';
import { Text, View, Dimensions, TouchableWithoutFeedback } from 'react-native';
const screenWidth = Dimensions.get('window');
export default class App extends Component {
constructor() {
super();
this.state = { "lastClicked" : "None" };
this.buttonPress = this.buttonPress.bind(this);
}
createButton(id) {
return (
<TouchableWithoutFeedback onPress={() => this.buttonPress(id)}>
<View style={{flex: 3, justifyContent:'center', alignItems:'center'}}>
<Text style={{fontSize:30}}>{id}</Text>
</View>
</TouchableWithoutFeedback>
);
}
buttonPress(id) {
this.setState({ "lastClicked" : id });
}
render() {
return (
<View style={{alignContent: "stretch"}}>
<View style={{width: screenWidth}}>
<Text style={{fontSize: 30}}>This is a JavaScript Calculator</Text>
<Text style={{fontSize: 20}}>You clicked: {this.state.lastClicked}</Text>
</View>
<View style={{width:screenWidth}}>
<View style={{height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch",}}>
{this.createButton("7")}
{this.createButton("8")}
{this.createButton("9")}
</View>
<View style={{height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch"}}>
{this.createButton("4")}
{this.createButton("5")}
{this.createButton("6")}
</View>
<View style={{height: 150, flexDirection : "row", alignItems: "stretch", alignContent: "stretch", alignSelf: "stretch"}}>
{this.createButton("1")}
{this.createButton("2")}
{this.createButton("3")}
</View>
</View>
</View>
);
}
}
Demo on snack.expo.io

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