Check this snippet:
import React, { Component } from 'react';
import { Text, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row'}}>
<View>
<Text style={{width:50}}>Test </Text>
</View>
<View style={{backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}
The text with yellow background is rendered partially outside the view with the black border.
This can be tested here: https://snack.expo.io/HJRRjutuW
Why doesn't it render properly? And what should I change so it does?
Just remove flexDirection: 'row' from
<View style={{margin:5, flexDirection: 'row'}}>
also updated snack
https://snack.expo.io/rJ6N8tKdb
Or you can add flexWrap
<View style={{margin:5, flexDirection: 'row',flexWrap: 'wrap'}}>
output will be like
EDIT
import React, { Component } from 'react';
import { Text, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between'}}>
<View >
<Text style={{width:50}}>Test </Text>
</View>
<View style={{flex:1,backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}
If I measure the screenwidth and subtract the rest from it, it looks like I want it to, but this is not an elegant solution:
https://snack.expo.io/r1xCX5td-
import React, { Component } from 'react';
import { Text, View, Dimensions} from 'react-native';
export default class App extends Component {
render() {
let stretchWidth = Dimensions.get('window').width - 240;
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between'}}>
<View style={{flexDirection: 'row'}}>
<Text style={{width:50}}>Test</Text>
</View>
<View style={{width:stretchWidth,backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}
Related
I am using react-native and expo. I have some data that is displayed on the screen (this is my second screen) such as:
updated:
const x ="key";
const storeData = async (value) => {
try {
const jsonValue = JSON.stringify(movie)
console.log(jsonValue);
await AsyncStorage.setItem(x,jsonValue)
console.log("storing..");
} catch (e) {
// saving error
console.log("error storing...");
}
}
const getData = async () => {
try {
const jsonValue = await AsyncStorage.getItem(x)
console.log(jsonValue);
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch(e) {
// error reading value
console.log("error getdata");
}
}
let item = state.myListData.length && state.myListData[0];
let movie = (
<View>
<View
style={{
flexDirection: 'row',
backgroundColor: 'black',
alignItems: 'center',
}}>
<Text style={{ width: '50%', color: 'white' }}>{item.symbol}</Text>
<Text style={{ width: '10%', color: 'white' }} key={item.open}>
{item.open}
</Text>
<Text
style={{
width: '30%',
color: 'white',
backgroundColor: 'red',
marginVertical: 5,
paddingHorizontal: 10,
borderRadius: 10,
}}
key={item.close}>
{item.close}
</Text>
</View>
<View style={styles.bottomdata}>
<Text style={[styles.text, { alignSelf: 'center' }]} key={item.name}>
{item.name}
</Text>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>OPEN</Text>
<Text style={styles.text}>{item.open} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>CLOSE</Text>
<Text style={styles.text}>{item.close}</Text>
</View>
</View>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>LOW</Text>
<Text style={styles.text}>{item.low} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>HIGH</Text>
<Text style={styles.text}>{item.high}</Text>
</View>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>VOLUME</Text>
<Text style={styles.text}>{item.volumes}</Text>
</View>
</View>
</View>
);
How do I save this data to my screen even though if user goes back to first screen and comes back to second screen it should still be there, but it disappears at the moment since I am not sure how to store it in local storage.
I looked up online and wrote this:
const x = {key:"value"}
savingdata = () => {
if (movie){
let storeData = async () => {
try {
await AsyncStorage.setItem(
'x',
movie
);
console.log(storeData);
} catch (error) {
// Error saving data
console.log(error);
}
};
}
};
This doesn't work at all. I am new to saving data so I am not sure how to do it. If someone can please help me?
That's my whole code for second screen:
import React, { useState, useEffect } from "react";
import { AsyncStorage } from "react-native";
import {
TouchableWithoutFeedback,
Keyboard,
FlatList,
TextInput,
Button,
Text,
} from "react-native";
import {
StyleSheet,
View /* include other react-native components here as needed */,
} from "react-native";
import { useStocksContext } from "../contexts/StocksContext";
import { scaleSize } from "../constants/Layout";
// FixMe: implement other components and functions used in StocksScreen here (don't just put all the JSX in StocksScreen below)
export default function StocksScreen({ route, navigation }) {
const { ServerURL, watchList } = useStocksContext();
const [state, setState] = useState({
myListData: [],
_storeData:[]
/* FixMe: initial state here */
});
const { stuff } = route.params;
renderWithData = () => {
return fetch(`http://131.181.190.87:3001/history?symbol=${stuff}`)
.then((res) => res.json())
.then((json) => {
setState({
isLoaded: true,
myListData: json,
});
// console.log(state.myListData[0]);
});
};
useEffect(() => {
renderWithData();
savingdata();
// FixMe: fetch stock data from the server for any new symbols added to the watchlist and save in local StocksScreen state
}, [watchList]);
//let item = state.myListData[0];
let item = state.myListData.length && state.myListData[0];
let movie = (
<View>
<View
style={{
flexDirection: 'row',
backgroundColor: 'black',
alignItems: 'center',
}}>
<Text style={{ width: '50%', color: 'white' }}>{item.symbol}</Text>
<Text style={{ width: '10%', color: 'white' }} key={item.open}>
{item.open}
</Text>
<Text
style={{
width: '30%',
color: 'white',
backgroundColor: 'red',
marginVertical: 5,
paddingHorizontal: 10,
borderRadius: 10,
}}
key={item.close}>
{item.close}
</Text>
</View>
<View style={styles.bottomdata}>
<Text style={[styles.text, { alignSelf: 'center' }]} key={item.name}>
{item.name}
</Text>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>OPEN</Text>
<Text style={styles.text}>{item.open} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>CLOSE</Text>
<Text style={styles.text}>{item.close}</Text>
</View>
</View>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>LOW</Text>
<Text style={styles.text}>{item.low} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>HIGH</Text>
<Text style={styles.text}>{item.high}</Text>
</View>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>VOLUME</Text>
<Text style={styles.text}>{item.volumes}</Text>
</View>
</View>
</View>
);
const x = {key:"value"}
savingdata = () => {
if (movie){
let storeData = async () => {
try {
await AsyncStorage.setItem(
'x',
movie
);
console.log(storeData);
} catch (error) {
// Error saving data
console.log(error);
}
};
}
};
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
{movie}
</View>
</TouchableWithoutFeedback>
);
}
I want to save data in different class, if that possible, so my code is not messy. But, saving in the same class in okay as well whatever works. Any help is appreciated.
I'm trying to get a TouchableWithoutFeedback wrapped ScrollView work.
In the real problem I'm unable to access the ScrollView.
Here's a working Expo Snack for easy testing.
And here's the code.
import * as React from 'react';
import {
Text,
View,
StyleSheet,
ScrollView,
FlatList,
TouchableWithoutFeedback,
} from 'react-native';
import Constants from 'expo-constants';
import LongText from './components/LongText';
export default class App extends React.Component {
render() {
return (
<View style={{ flex: 1, paddingTop: Constants.statusBarHeight }}>
{/* https://stackoverflow.com/a/46606223/25197
BROKE on iOS
*/}
<TouchableWithoutFeedback onPress={() => console.log('Pressed 2')}>
<View style={[styles.container, { borderColor: 'red' }]}>
<Text style={styles.label}>
{'2) Touchable > View > View > ScrollView\n'}
{' - iOS: BROKE\n - Android: WORKING\n'}
</Text>
<View
style={{ flex: 1 }}
onStartShouldSetResponder={() => true}
// onStartShouldSetResponderCapture={() => true}
onResponderGrant={() => console.log('Granted View 2')}>
<ScrollView
style={{ flex: 1 }}
keyboardShouldPersistTaps={true}
onResponderGrant={() => console.log('Granted ScrollView 2')}>
<LongText />
</ScrollView>
</View>
</View>
</TouchableWithoutFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
borderWidth: 5,
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
label: { fontWeight: 'bold' },
});
The ScrollView works as expected on Android.
How can I get it working on iOS?
In the real problem I'm unable to access the ScrollView.
Snack working link https://snack.expo.io/#mehran.khan/touchable-wrapped-scrollview
You should change this code
<View
style={{ flex: 1 }}
onStartShouldSetResponder={() => true}
// onStartShouldSetResponderCapture={() => true}
onResponderGrant={() => console.log('Granted View 2')}>
<ScrollView
Add onStartShouldSetResponder={() => true} to View instead of Scrollview
<ScrollView
style={{ flex: 1 }}>
<View onStartShouldSetResponder={() => true}><LongText /></View>
</ScrollView>
App Preview
I would like to show on the homepage of my react native app , a view that in turn shows a text element and an icon, then below these 2 I would like to show the amazon logo. I tried but it only shows me the logo.
export default class Header extends Component {
render() {
return (
<View style={{ flex: 1, flexDirection: 'row' }}>
<Text style={styles.Title}>Acquista!</Text>
<Ionicons name="ios-contact" size={42} color='red' style={{ marginTop:
65, marginLeft: 210 }} />
</View> ,
<Logo></Logo>
);
}
}
class Logo extends Component {
render() {
return (
<View>
<Image
style={{ height: 200, width: 200, marginTop: 150 }}
source={require('./assets/images/amazon.jpg')}
/>
</View>
);
}
}
Wrap everything into a View
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<Text style={styles.Title}>Acquista!</Text>
<Ionicons name="ios-contact" size={42} color='red' style={{ marginTop: 65, marginLeft: 210 }} />
</View>
<Logo />
</View>
)
I have a simple View which has two children, another View and a ScrollView. The ScrollView should be 5x higher than the View on the same level, using flexbox.
<View style={{ flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<ScrollView style={{flex: 5, backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
So I simply added flex:1 and flex:5 to the children Views, but the in the rendered view both of them fit exactly to half of the screen. It looks as if the two flex attributes are ignored...
Btw, using a second View instead of the ScrollView works just fine!
Any ideas how to achieve the 1:5 ratio with a ScrollView?
ScrollView is a component which doesn't inherit the use of flex. What you want to do is wrap the ScrollView in a View which will create the flex ratio you desire.
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<View style={{flex: 5}}>
<ScrollView style={{backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
</View>
To achieve 1:5 screen ratio, having child component View and ScrollView with respect to parent View, you can code it in following manner:
<View style={{ flex: 1}}>
<View style={{flex: 1/5, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<ScrollView style={{flex: 4/5, backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
I am using react-native-deck-swiper and have cards with buttons on them. The buttons do not work on iPhone 7 only. Tried several phones. What's even more interesting is that react-native-tinder-swipe-cards has the same issues, so it seems to be something that I'm doing wrong. Code:
import React from 'react';
import {Alert, Text, TouchableHighlight, View, StyleSheet} from "react-native";
import Swiper from "react-native-deck-swiper";
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Swiper
ref='swiper'
cards={['asdf','23423']}
renderCard={(question) => {
return (
<TouchableHighlight
onPress={() => Alert.alert('I work')}>
<Text> {question} </Text>
</TouchableHighlight>
)
}}
cardIndex={0}
>
</Swiper>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Same code without swiper works fine:
import React from 'react';
import {Button, Alert, Text, TouchableHighlight, View, StyleSheet} from "react-native";
import Swiper from "react-native-deck-swiper";
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableHighlight
onPress={() => Alert.alert('asdf')}>
<Text> I like pants </Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I highly appreciate any help. Thanks!