How to make parent's width wrap its content in React Native? - reactjs

I am new to React Native so this might be a silly question.
What I am trying to get is something like this :
Where I have a parent view with 2 children, Image and Text, aligned vertically to the left. What I want is the parent view to cover only the width of its children. But instead what I get is this :
The parent view stretches to the complete width of the mobile screen.
Here is my code :
render () (<View style={{backgroundColor: '#333333'}}>
<Image source={btnImageSource} />
<Text>Some label</Text>
</View>);
Something similar to Android's 'wrap-content' width value.

You will be able to do this using flex. I found this guide to be very helpful when working with flex.
A good starting point would be to create a parent View that is flexDirection: row, justifyContent: flex-start
render () (
<View style={{justifyContent: 'flex-start', flexDirection: 'row'}}>
<View style={{backgroundColor: '#333333'}}>
<Image source={btnImageSource} />
<Text>Some label</Text>
</View>
</View>
);

Related

React Native/Flexbox align Text bottom right inline with other Text

I'm trying to design a Message Bubble like this:
Source: Telegram iOS App
Where the Message itself is a <Text> component, and the timestamp <Text> is nested inside the Message's <Text>:
return (
<MessageBubble {...props}>
<Text style={fontStyle}>
{message.text}
<Text style={timestampStyle}>
{message.timestamp}
</Text>
</Text>
</MessageBubble>
);
The above code looks like this:
As you can see, the timestamp renders immediately at the end of the message content, but I want it to align at the bottom right.
I tried to set timestampStyle to alignSelf: 'flex-end', flex: 1, flexGrow: 1, etc but it didn't render at the bottom right.
Note: I don't want to use position: 'absolute' since that would like this:
Does anyone have an idea how I can achieve the style of the Telegram message bubble with React Native's Flexbox system?

KeyboardAvoidingView doesn't work inside tab navigation

I'm using the built-in KeyboardAvoidingView in react native and when I use the code below in a screen where you can't see the tabs (like in a modal) it works perfectly fine and the keyboard doesn't cover any content whatsoever, but when I use the exact same code but in a screen that is used in tab navigation the keyboard covers some content, it's like the KeyboardAvoidingView doesn't take into consideration the height of the bottom tabs
Here's my code:
<KeyboardAvoidingView style={{flex: 1}} behavior="padding">
<ScrollView keyboardShouldPersistTaps="handled">
{content}
</ScrollView>
<TextInput
style={{height: 50, width: "100%", backgroundColor: "red"}}
placeholder="Test input"
/>
</KeyboardAvoidingView>

react native text box above scrollable-tab-view

New to react native, trying to place text-box above scrollable tab view
export default React.createClass({
render() {
return
<View>
<TextInput
style={{height: 50}}
placeholder="Enter!"
onChangeText={(searchText) => this.setState({searchText})}/>
<ScrollableTabView
style={{marginTop: 10, }}
initialPage={1}
renderTabBar={() => <FacebookTabBar />}
>
<ScrollView tabLabel="ios-search" style={styles.tabView}>
<View style={styles.card}>
<TextInput
style={{height: 50}}
placeholder="Enter!"
onChangeText={(searchText) => this.setState({searchText})}/>
</View>
</ScrollView>
</ScrollableTabView>
</View>
;
},
});
Scrollable tab view doesn't show up with above code, I am unable to understand why, please advice. I am trying to make something like Linkedin app.
<ScrollableTabView> is styled with flex: 1, so you need to explicitly set flex: 1 to its parent like this in order to show it:
return (
<View style={{flex: 1}}>
...
</View>
);
Here is a quote from React Native documentation regarding Flex:
A component can only expand to fill available space if its parent has
dimensions greater than 0. If a parent does not have either a fixed
width and height or flex, the parent will have dimensions of 0 and the
flex children will not be visible.

Scroll View inside view not working react native

Here I am trying a simple code but the scroll view is not working if kept inside another view. Code is like this:
return(
<View>
<Toolbar title={this.props.title}>
</Toolbar>
<ScrollView>
<HomeScreenTop />
<HomeScreenBottom navigator={navigator}/>
</ScrollView>
</View>
);
But if scroll view kept as parent view it works perfectly. Code is as below:
return(
<ScrollView>
<Toolbar title={this.props.title}>
</Toolbar>
<HomeScreenTop />
<HomeScreenBottom navigator={navigator}/>
</ScrollView>
);
Now the problem is I don't want my toolbar to scroll up and down, I just want the contents below the toolbar to move. How can I achieve that?
And next question: Is scroll view has to be parent view to be returned to work?
Use the property flexGrow in the style, flex didnt worked for me.
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
...
</ScrollView>
you should wrap toolbar in view like this:
<View><Toolbar/></View>
Wrap those component which you want to scroll inside scrollview as:
<ScrollView>your expected components...</ScrollView>
And provide flex to root view as:
<View style={{flex:1}}>
Finally your code will run as you expected.
Top <View> must has style flex:1, and also <ScrollView> has too
This was driving me crazy because I added <view> and <ScrollView> like everyone suggested but nothing worked. Then I closed the terminal then rebuild the application again using:
npx react-native run-android
Then, it started working. I hope this saves someone's sanity :)
FYI, just hitting r (or refreshing) was not working either. I had to rebuild it.
For me, Scroll View wrapped with TouchableWithoutFeedback was causing scroll view to not function at times.
I set height property for style . then it's work for me .
My code :
<View style={styles.listWrapper}>
<ScrollView >
<XYZ/>
</ScrollView>
</View>
Styles :
listWrapper:{
// flex:1,
// flexGrow:1,
width:'80%',
height:300,
},
Dont use contentContainerStyle on Scroll View Just use simple style prop for styling of scroll View . You will not face any problem.
None of these solution worked for me, after very long I found that height of a View inside the code is causing the problem so instead of
height:'50%'
I change it to
height:300
and it worked, as show below:
<ScrollView>
...
<View
style={{
flexDirection: 'row',
height: 100,
justifyContent: 'space-evenly',
height:300,
backgroundColor: '#fff',
padding: 20,
margin: 5,
}}>
...
</ScrollView>
If you are using <Form> from native base and you want to scroll
then use KeyboardAwareScrollView
<KeyboardAwaareScrollView enableOnAndroid={true}>
.
.
</KeyboardAwareScrollView>
this will work on Android
I have solved in this way:
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;
<View
style={{
overflow: "hidden",
flex: 1,
borderTopStartRadius: 40,
borderTopEndRadius: 40,
flexGrow: windowHeight,
}}
>
<ScrollView
contentContainerStyle={{
flexGrow: windowHeight,
backgroundColor: Colors.primary_color,
padding: 10,
}}
>
</View>
...
</ScrollView>
Update 2020-02: It will work with React.Fragment <> and </> or <React.Fragment> and </React.Fragment>. So Try this.
return(
<>
<Toolbar title={this.props.title}>
</Toolbar>
<ScrollView>
<HomeScreenTop />
<HomeScreenBottom navigator={navigator}/>
</ScrollView>
</>
);
Use react fragments instead of a View to wrap your scroll view it worked for me
<>
<ScrollView>
..........
</ScrollView>
</>
if you are using position: "absolute", delete it and try.
You can try
<SafeAreaView>
<ScrollView>
</ScrollView>
</SafeAreaView>

How react native Text and Image responsive? smaller text and image in small device, bigger text and image in large device

How react native Text and Image responsive?
I only know the Flexbox can make layout responsive but seems can not apply in text and image.
e.g.Make my text and image smaller in iphone 4s, bigger in iphone 6
Thanks.
You can use Flexbox in order to make your application responsive.
For example, say you wanted to display a line of text and an image on the same line:
class ResponsiveExample extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>
Example of centered text
</Text>
<Image
resizeMode={"contain"}
style={styles.image}
source={{uri: "your image"}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
text: {
marginLeft: 20,
flex: 1
},
image: {
marginRight: 20,
height: 400,
flex: 3,
}
});
Now the text and image will be displayed relative to the screen size. The usual hangup here is that flexDirection defaults to column, which will make things line up vertically. You can see what happens when we flip from portrait to landscape orientation:
As you can see, the text and image respond to the change in orientation.
For a better overview of Flexbox, I like to refer to the following guide:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/.
Just keep in mind that React Native defaults to a flex-direction of column, so if you want things laid out horizontally, you'll have to explicitly set it to row.
I think react-native-fit-image is useful for you.
React Native Fit Image enables you to draw responsive image component.
You can use this component as below.
<FitImage
source={{ uri: 'http://facebook.github.io/react/img/logo_og.png' }}
style={styles.fitImage}
/>
You are right to think about Flexbox, simply wrap your Text and Image inside View and make those View flexbox responsive.

Resources