I applied Animated.View to the Card component and ScrollView to the CardMain component. And pressable is applied to the child component, called ModeContainer. In ModeContainer, changemodefunc is executed when onPress is triggered.
When I run in emulator and press ModeContainer(Pressable), onPress runs fine, changemodefunc works fine. However, problem is if I connect it to a real device and run it, it will not run even if I press ModeContainer(Pressable). How do we solve this problem?
i'm using window and Emulator
this is my code
import {
Animated,
View,
ScrollView,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
const Container = styled(LinearGradient)`
flex: 1;
justify-content: center;
align-items: center;
`;
const SecondContainer = styled.View`
flex: 9.1;
`;
const Card = styled(Animated.createAnimatedComponent(View))`
flex: 1;
`;
const CardWapper = styled(LinearGradient)`
flex: 1;
`;
const CardMain = styled(ScrollView)`
flex: 9;
`;
const ModeWrapper = styled.View`
flex:1;
`;
const ModeContainer = styled.Pressable`
`;
const IconCon = styled.Pressable`
width: 50px;
`;
<Container
>
<SecondContainer
>
<Card
style={{
transform: [...POSITION.getTranslateTransform()],
}}
>
<CardWapper>
<CardMain>
<ModeWrapper>
(
<ModeContainer
onPress={() => changemodefunc('black')}>
<IconCon
>
</IconCon>
</ModeContainer>
)
</ModeWrapper>
</CardMain>
</CardWapper>
</Card>
</SecondContainer>
</Container>
Related
I am learning React Native and I am having trouble displaying the ImageBackground component.
The ImageBackground has source that points to an image in the same folder, despite this is still not visible unless I give the ImageBackground a height in number, because if I try to give it a height in % it still won't show itself.
Here is the code for the component execpt the style:
import React from 'react';
import { View, ImageBackground, StyleSheet, Text } from 'react-native';
export default function WelcomeScreen(props) {
return (
<View>
<Text>Welcome</Text>
<ImageBackground source={require('./background.jpg')} style={styles.background} />
</View>
);
}
Trying different ways to style it, the ImageBackground has different behaviors regarding showing itself:
This will not show ImageBackground:
const styles = StyleSheet.create({
background: {
flex: 1,
},
});
This won't either:
const styles = StyleSheet.create({
background: {
flex: 1,
height: '100%',
},
});
This will show it:
const styles = StyleSheet.create({
background: {
flex: 1,
height: 300,
},
});
I do not understand why this happens. From my understanding the size should be added only when the image is from the net, and regardless this, the % value should still work.
What am I missing here?
EDIT:
I made a workaround for this using Dimension and feeding the screen height to the ImageBackground:
import { View, ImageBackground, StyleSheet, Dimensions } from 'react-native';
const { height } = Dimensions.get('screen');
const styles = StyleSheet.create({
background: {
flex: 1,
height,
},
});
Though it works, the question why do I need to set a height for an image in the same folder still stand.
if you want to give a value in percentage in such cases you should use some tricks like:
background: {
height: deviceHeight,
},
container: {
height: deviceHeight * 50 / 100,
}
or you can use a popular library in the name of react-native-responsive-screen. This library is going to give you the power to give relative values and convert them to absolute values behind the scene.
The snippet below is going to show how to use it:
import {widthPercentageToDP, heightPercentageToDP} from 'react-native-responsive-screen';
const styles = StyleSheet.create({
background: {
height: heightPercentageToDP('100%'),
}
})
This should work as you expected ;)
If you want your background image to cover your entire view, try something like this:
<View>
<ImageBackground style={styles.image} resizeMode={'cover'} source={require('../Images/test.jpg')}>
{/*your components*/}
</ImageBackground>
</View>
with this styling:
const styles = StyleSheet.create({
image: {
height: '100%',
width: undefined,
}
})
I was asked to add an horizontal scrollview inside of a drawer. (Think Instagram stories but in a drawer.) The animation works very inconsistent. The most annoying is swiping to the left, the scrollview often doesn't scroll and the drawer starts the closing animation instead.
The drawer already exists for awhile, so setup issues are not the problem.
Here is my code:
// Drawer.navigator
const DrawerContent = () => {
// UI of the drawer
return <Drawer activeRoute={activeRoute} />;
};
return (
<DrawerNav.Navigator
drawerContent={DrawerContent}
drawerStyle={{ width: 320 }}
initialRouteName="Home"
drawerContentOptions={{
someColor: theme.someColor,
}}
>
// other screens
</DrawerNav.Navigator>
import { ScrollView } from 'react-native';
const Container = styled.View`
height: 62.5px;
flex-direction: row;
align-items: center;
justify-content: center;
`;
const ThingWrapper = styled(Flex)`
height: 62.5px;
align-items: center;
justify-content: center;
.lastBubble {
margin-right: 16px;
}
`;
...
<Container>
<ScrollView
horizontal
vertical={false}
directionalLockEnabled
nestedScrollEnabled
showsHorizontalScrollIndicator={false}
pinchGestureEnabled={false}
contentContainerStyle={{
zIndex: 9999,
}}
>
{thingsToRender.map((thing, index) => {
return (
<ThingWrapper>
<AnyThing thingId={thing.id} />
</ThingWrapper>
);
})}
</ScrollView>
</Container>
I think element focus might be the main problem here, but I don't know how to fix this. Any help is greatly appreciated. Thanks!
I fixed it by creating this object and giving it as a param to every screen. As a con this disable the drawer swipe open/close.
const drawerScreenOptions = {
gestureEnabled: true,
swipeEnabled: false,
};
// Drawer.navigator
const DrawerContent = () => {
// UI of the drawer
return <Drawer activeRoute={activeRoute} />;
};
return (
<DrawerNav.Navigator
drawerContent={DrawerContent}
drawerStyle={{ width: 320 }}
initialRouteName="Home"
>
// !! Give options to all screens
<DrawerNav.Screen
name="screenX"
component={ScreenXNavigator}
options={drawerScreenOptions}
/>
</DrawerNav.Navigator>
Sorry I know this probably is a stupid question but I'm new to React Native and I can't seem to find a solution to this looking it up. Thank you in advance for your help.
I'm trying to give the HeadingWrapper a box-shadow but it seems to give the shadow to the inner contents. Here is my code that produces this result:
import React, { Component } from 'react';
import styled from 'styled-components';
import H1 from "../common/headings";
import LeftArrow from "../assets/LeftArrow.png";
const MainWrapper = styled.View`
box-shadow: 5px 5px 5px #000000;
`;
const HeadingWrapper = styled.View`
padding: 60px 10px 0 10px;
height: 60px;
flex: 1;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
`;
const ScrollArea = styled.ScrollView`
`;
const Img = styled.Image`
`;
class LandingPage extends Component {
render() {
return (
<MainWrapper style={styles.mainWrapper}>
<HeadingWrapper>
<Img style={styles.leftArrow} source={LeftArrow}/>
<H1>Chats</H1>
</HeadingWrapper>
<ScrollArea>
</ScrollArea>
</MainWrapper>
);
}
}
headings.js:
import styled from 'styled-components';
import React from "react";
const InnerH1 = styled.Text`
font-size: 34px;
font-weight: bold;
`;
const H1Container = styled.View`
flex: 1;
`;
const H1 = (props) => {
return (
<H1Container>
<InnerH1>{props.children}</InnerH1>
</H1Container>
)
};
export default H1;
Currently, the background color of HeadingWrapper is transparent as no background color is currently specified.
To create the 'box-shadow', all you need to do is give HeadingWrapper a background color of which is the same as your background.
Per the screenshot provided, the background color is white. Thus, you can use white as the background color for HeadingWrapper.
For inline style, you can use the below code:
<HeadingWrapper style={{ backgroundColor: 'white' }}>
<Img style={styles.leftArrow} source={LeftArrow}/>
<H1>Chats</H1>
</HeadingWrapper>
I have the following React-Native code which alerts the user that it was pressed, however it does not respond to anything.
I have tried using different Touchable components but none seem to work, the only one is Button but that's not really what I want, I'm building a slider so a button is not really appropriate for this.
Anyway, here's my code:
import React, {Component} from 'react';
import {View, TouchableWithoutFeedback, Alert, Text} from 'react-native';
import styles from './styles.js';
import LinearGradient from 'react-native-linear-gradient';
export default class BrightnessSlider extends Component {
value: 100;
constructor(...args) {
super(...args);
}
render() {
return (
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={["#222", "#ddd"]} style={styles.brightnessSliderRunnable}>
<View style={styles.brightnessSliderTrack}>
<TouchableWithoutFeedback onPress={() => Alert.alert("Hello World")}>
<View style={styles.brightnessSliderThumb} />
</TouchableWithoutFeedback>
</View>
</LinearGradient>
)
}
}
and ./styles.js
import {StyleSheet} from "react-native";
export default styles = StyleSheet.create({
brightnessSliderRunnable: {
top: 50,
height: 9,
width: width - 20,
left: 10,
backgroundColor: "#555",
opacity: 1,
elevation: 1,
borderWidth: 0
// position: "absolute"
},
brightnessSliderThumb: {
width: 23,
height: 23,
borderColor: "#888",
// opacity: 1,
borderWidth: 2,
backgroundColor: "#ffffff",
position: "absolute",
top: -7,
borderRadius: 5,
elevation: 2
},
brightnessSliderTrack: {
width: "100%",
elevation: 1,
borderWidth: 0
}
});
Thanks for any help
Questioner's original code.
Solution
Added by questioner's solution.
Change position: absolute to position: relative.
Change your style type made by StyleSheet as below.
Your original.
{...styles.colourContainer, opacity: 100 - this.darkness}
Recommend way.
[styles.colourContainer, {opacity: 100 - this.darkness}]
I tested code and it works well when we touch the white square.
Tested on iOS.
Original App.js.
App.js changed by me.
import React, {Component} from 'react';
import {View, Dimensions, Text} from 'react-native';
import BrightnessSlider from '../components/BrightnessSlider';
import styles from '../components/TempStyle.js';
const d = Dimensions.get('window'),
width = d.width,
height = d.height;
export default class BrightnessSliderTest extends Component {
constructor(...args) {
super(...args);
this.darkness = 0;
this.prevColours = ["#ff0000", "#00ff00", "#0000ff"];
}
render() {
// It is not possible just access the style created by StyleSheet.create(). Do not use StyleSheet.create() or change to flatten the StyleSheet object.
const sty = [styles.colourContainer,{ opacity: 100 - this.darkness}];
return (
<View style={styles.container}>
<View style={sty}>
<View style={styles.toolBar}>
<View style={styles.colourPalette}>
{this.prevColours.map((i, a) => <View key={String(a)} style={[styles.colourTile, {backgroundColor: i}]}/>)}
</View>
{/* <Button title={"Save To Palette"} onTap={this.saveToPalette}>Save</Button> */}
</View>
<BrightnessSlider />
</View>
</View>
);
}
}
Why?
I am not sure how you can use your component in other components. But if you do not have container having enough size can show your component, touch area may not work. That is why I use backgroundColor for container sometimes in testing.
Added after testing full code used in question.
It is not possible just access the style through like spread operator created by StyleSheet.create(). Do not use StyleSheet.create() or change to flatten the StyleSheet object.
And Style can be worked differently from platforms(iOS, Android).
I'm trying to create a component with React Native that includes a <Text> component inside the wrapped component:
const MyComponent = props => (
<View {...props}>
<Text {...props}>Hello world</Text>
<View>
)
const MyRedComponent = styled(MyComponent)`
color: #000;
margin-left: 10px;
background: #F00;
`
I'm composing my component this way so I could change the the text color from the same styled component as I'm changing the background color:
const MyBlueComponent = styled(MyRedComponent)`
color: #FFF;
background: #00F;
`
However with this approach there is a problem that all of the styles get applied to the <Text> component, not only the color; in this example the <Text> component also gets the margin-left style from the parent styles which is not preferred. I'd only like the text color to be cascaded to the <Text> component.
Is this possible using Styled Components with React Native?
You can create a wrapper function using StyleSheet.flatten and pick the color from the resulting object:
const MyComponent = props => (
<View {...props}>
<Text style={{ color: StyleSheet.flatten(props.styles).color }}>Hello world</Text>
<View>
)
const MyRedComponent = styled(MyComponent)`
color: #000;
margin-left: 10px;
background: #F00;
`
It makes sense to extract the picking to its own function. For example you could create the following wrapper:
const pickColorFromStyles = styles => {
const { color } = StyleSheet.flatten(styles)
return { color }
}
...and use that function in your component:
const MyComponent = props => (
<View {...props}>
<Text style={pickColorFromStyles(props.styles)}>Hello world</Text>
<View>
)
Notice the warning with using StyleSheet.flatten from the documentation page:
NOTE: Exercise caution as abusing this can tax you in terms of optimizations. IDs enable optimizations through the bridge and memory in general. Refering to style objects directly will deprive you of these optimizations.