React native view layer - reactjs

I'm trying to put a white dot over a green square like below.
But no matter how I try I still get this. The background color and margin of the white dot is gone.
Here's the code.
<View style={backgroundColor: 'white', zIndex: 1, margin: 2, borderRadius: 10, borderWidth: 2} >
<View style={backgroundColor: 'green', zIndex: 0} />
</View>
I though zIndex will solve my problem but it doesn't. I've also tried swapping the order but it just give me a plain green square. Help?
<View style={backgroundColor: 'green', zIndex: 0}>
<View style={backgroundColor: 'white', zIndex: 1, margin: 2, borderRadius: 10, borderWidth: 2} />
</View>

I don't think you need/want to use z-index for this. z-index is used for depth, to layer items that occupy the same space.
Read up on it here: CSS Tricks - z-index
I'd agree that you want to make use of flexbox if you're trying to keep everything aligned.
Here's an example:
<View style={styles.container}>
<View style={styles.holder}>
<View style={styles.circleHolder}>
<View style={styles.circle} />
</View>
<View style={styles.square} />
</View>
</View>
and the styling:
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
circleHolder: {
width: 200,
height: 200,
justifyContent: 'center',
alignItems: 'center'
},
circle: {
backgroundColor: 'white',
width: 150,
height: 150,
borderRadius: 75,
borderWidth: 2
},
square: {
backgroundColor: 'green',
width: 200,
height: 200,
},
});
RNPlay: https://rnplay.org/apps/k5DbDQ

<View>
<View style={
backgroundColor: 'white',
zIndex: 1,
margin: 2,
borderRadius: 10,
borderWidth: 2
}/>
<View style={backgroundColor: 'green', zIndex: 0}/>
</View>
Try this. You shouldn't be nesting them, because they are related to each other as a parent and child. By the way you might need to use flex to align them correctly :)

Related

How can I make the a TextInput adapt size to avoid the keyboard?

I am working with a packaged component that has a toolbar (containing bold, italics, underline, etc. buttons) and an editor (like a TextInput).
I would like the toolbar to be just above the keyboard and the editor to change its height dynamically to take up the rest of the vertical place (between the header and the toolbar).
This is what I have so far, the toolbar is just below a horizontal scrollview (the squares will be images later). How can I make this toolbar attach itself to the keyboard, and the textInput's height dynamic to fill the rest of the screen above it, until the header?
Here's the code I have so far, not sure how to make these dynamic!
<View behavior={'padding'} >
<RichEditor
style={{ minHeight: 150 }}
/>
<ScrollView horizontal={true} style={{ backgroundColor: 'green' }}>
<View style={{ backgroundColor: 'white', height: 60, width: 60, borderRadius: 15, borderColor: 'black', borderWidth: 1 }} />
<View style={{ backgroundColor: 'white', height: 60, width: 60, borderRadius: 15, borderColor: 'black', borderWidth: 1 }} />
<View style={{ backgroundColor: 'white', height: 60, width: 60, borderRadius: 15, borderColor: 'black', borderWidth: 1 }} />
<View style={{ backgroundColor: 'white', height: 60, width: 60, borderRadius: 15, borderColor: 'black', borderWidth: 1 }} />
</ScrollView>
<KeyboardAvoidingView>
<RichToolbar e/>
</KeyboardAvoidingView>
</View>
wrap the entire view in KeyboardAvoidingView. then let your Richtoolbar stick to bottom.
<KeyboardAvoidingView
behavior={Platform?.OS == 'ios' ? 'padding' : 'height'}
style={{flex: 1}}
enabled
keyboardVerticalOffset={34}> //adjust the offset to adjust position
<View style={{ flex: 1, paddingBottom: 4 }} >
//Content here
</View>
<View
style={{
height: 100, //or whatever height richtoolbar is
}}>
RICHTOOLBAR HERE
</View>
{/*<KeyboardSpacer topSpacing={-40}/> */}
</KeyboardAvoidingView>

How to wrap title on to new line react native

I was wondering how to wrap the title on to another line or possibly 2 lines before cutting off...
I tried flex wrap but im possibly not applying it correctly. Or if theres some javascript I could add to the ternary. Apologies if this has already been answered I couldnt find it.
enter image description here
<View style={styles.titleWrapper}>
<Text style={styles.title}>
{title.length > 20 ? title.slice(0, 22) + "..." : title}
</Text>
<MaterialIcons name="favorite-border" color="#72bcd4" size={24} />
</View>
<View style={styles.descriptionWrapper}>
<Text style={styles.description}>
{description.length > 100 ? description.slice(0, 100) + "..." : description }
</Text>
</View>
</View>
</TouchableOpacity>
)
const styles = StyleSheet.create({
card: {
backgroundColor: "#fff",
height: 300,
margin: 20,
borderRadius: 10,
shadowColor: "black",
shadowOpacity: 0.25,
shadowOffset: {width: 0, height: 2},
shadowRadius: 8,
elevation: 5
},
imageWrapper: {
width: "100%",
height: "60%",
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
overflow: "hidden"
},
titleWrapper: {
height: "10%",
paddingHorizontal: 15,
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
marginTop: 10
},
You have specify the line count like
<Text style={styles.title} numberOfLines={2}>
{titile}
</Text>
React native will handle the ellipsis for you based on the lines

ripple effect leaking at corners as if Pressable button has a borderRadius

I'm using Pressable for buttons after referring this docs pressable docs
Now I want to add ripple effect to the button but it is not working properly.
<Pressable
android_ripple={{color: 'red', borderless: false}}
style={{backgroundColor: 'blue',borderRadius : 10}}>
<Text style={{alignSelf: 'center'}}>Button</Text>
</Pressable>
Ripple effect don't have border radius if button has radius.
it looks awkward that ripple effect corners go out of the curved radius.
Snack demonstrating the problem: https://snack.expo.dev/6U8dxxzLx
Nothing worked for me, So I solved this myself.
pressable should be wrapped in a view
view must have margin not padding
border radius must be on view not on pressable
pressable component must have padding not margin
then add ripple by android_ripple={{color: 'black', borderless: true}} to pressable.
<View style={styles.buttonView}>
<Pressable
onPress={() => {}}
android_ripple={{color: 'black', borderless: true}}
style={styles.loginButton}>
<Text style={styles.buttonText}>Login</Text>
</Pressable>
</View>
buttonView: {
alignSelf: 'stretch',
justifyContent: 'center',
borderRadius: 10,
elevation: 25,
margin: 10,
},
loginButton: {
height: 50,
backgroundColor: '#0f4c75',
padding: 10,
alignItems: 'center',
justifyContent: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
textTransform: 'uppercase',
fontFamily: 'sans-serif-light',
},
Update:-
Floating pressable component with ripple leakage fixed
<View style={{
position: 'absolute',
bottom: 250,
borderRadius: 50,
overflow: 'hidden',
alignSelf: 'center'
}}>
<Pressable
style={{
height: 60,
width: 60,
borderRadius: 50,
backgroundColor: 'red',
justifyContent: 'center',
alignItems: 'center',
elevation: 4,
}}
android_ripple={{
color: 'black',
}}
onPress={() => { console.log('om') }}>
<Text>O</Text>
</Pressable>
</View>
You can wrap pressable into View and pass borderRadius:10 and overflow:'hidden' to View style.
<View style={{ borderRadius: 10, overflow: 'hidden' }}>
<Pressable
android_ripple={{ color: 'red', borderless: false, }}
style={{ backgroundColor: 'blue', borderRadius: 10 }}>
<Text style={{ alignSelf: 'center' }}>Button</Text>
</Pressable>
</View>
Turns out the other solution don't cover all edge cases... I needed to wrap the view 2 times to manage elevation and shadow on iOS. (The button is in absolute position also).
export const PNFloatingButton = ({ children, ...props }) => {
return (
<View style={thisStyles.shadow}>
<View style={thisStyles.parentContainer}>
<Pressable style={thisStyles.button}
android_ripple={{ borderless: false, color: "#0F0" }}>
<Text>Button</Text>
</PNPressable>
</View>
</View>
)
}
const thisStyles = StyleSheet.create({
shadow: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.4,
shadowRadius: 4,
width: 56,
height: 56,
position: 'absolute',
elevation: 2,
right: 0,
bottom: 0,
},
button: {
padding: 4,
backgroundColor: "#F00",
},
parentContainer: {
// Pressable has issues with borderRadius on the ripple on android
overflow: "hidden",
borderRadius: 40,
},
})
For those that are using the Button element I found a simple workaround. Since this problem happens always when border od the button is changed (like became rounded) I just pass to the containerStyle of the button all the props + my button border radius. I add also the overflow property with hidden attribute.
Some little context: myButtonStyle is the style I want to apply to that button. If it's null, I'll apply a default style. Same for myContainerStyle.
The function inplemented before return():
function fixRippleBorder() {
const borderRadius = myButtonStyle
? EStyleSheet.flatten(myButtonStyle).borderRadius
: EStyleSheet.flatten(defaultButtonStyle).borderRadius;
return {
borderRadius: borderRadius,
overflow: 'hidden',
};
}
The button itself:
<Button
containerStyle={[
myContainerStyle ?? defaultContainerStyle,
fixRippleBorder(),
]}
buttonStyle={myButtonStyle ?? defaultButtonStyle}
...
You can add the style overFlow: 'hidden' to a view that wraps around your pressable object as long as that view also contains your borderRadius. Below is an example of a file I worked on recently that does this
import React from 'react';
import {Pressable, View, Text, StyleSheet, Platform} from 'react-native';
export default function CategoryGridTile({title, color, onPress}) {
return (
<View style={styles.gridItem}>
<Pressable
android_ripple={{color: '#ccc'}}
style={({pressed}) => [
styles.button,
pressed ? styles.buttonPressed : null,
]}
onPress={onPress}>
<View style={[styles.innerContainer, {backgroundColor: color}]}>
<Text style={styles.title}>{title}</Text>
</View>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
gridItem: {
flex: 1,
margin: 16,
height: 150,
borderRadius: 8,
elevation: 4,
backgroundColor: 'white',
shadowColor: 'black',
shadowOpacity: 0.25,
shadowOffset: {width: 0, height: 2},
shadowRadius: 8,
overflow: 'hidden',
},
button: {
flex: 1,
},
buttonPressed: {
opacity: 0.5,
},
innerContainer: {
flex: 1,
padding: 16,
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontWeight: 'bold',
fontSize: 18,
},
});

Inactive tab opacity (materialTopTabnavigator)

I have done a TopTabNavigator, and I set a background on One tab.
I want to know how can I remove the opacity when this tab is inactive.
I tried to do a condition with the same backgroundColor when focused or not.
Could anyone guide me how to approach this issue?
tabBarLabel: ({focused}) => (
focused ?
<View
style={{backgroundColor:'#FF6D70', height: 30, width: 60, justifyContent: 'center',
borderBottomLeftRadius: 10, borderBottomRightRadius: 10, marginLeft: 1}}>
<Text style={{color:'white', fontSize: 10, textAlign: 'center'}}>dashboard</Text>
</View> :
<View
style={{backgroundColor:'#FF6D70', height: 30, width: 60, justifyContent: 'center',
borderBottomLeftRadius: 10, borderBottomRightRadius: 10, marginLeft: 1}}>
<Text style={{color:'white', fontSize: 10, textAlign: 'center'}}>dashboard</Text>
</View> ),
Check this React Navigation.
There is a attribute called pressOpacity under tabBarOptions. May this helps you.
createMaterialTopTabNavigator({ /** Screens */ }, {
tabBarOptions:{
pressOpacity: 1 // Some value for pressed tab
... // Other Options
}
... // Other Options
});

How to force react native content to ignore keyboard?

I have tried using both KeyboardAvoidingView and ScrollView to prevent my content from being squished (pushed up) when the keyboard is present. I have tried using padding, height, and position for my behavior but nothing is working. Can someone please tell me how I can force my content to ignore the keyboard and not get pushed up??
return (
<View style={{height: '100%', backgroundColor: '#D6D6D6', position: 'relative'}}>
<View style={styles.wrapper}>
<View style={{height:'100%', borderRadius: 7}}>
<View style={styles.container}>
<ScrollView style={{borderRadius: 7}}
horizontal
showsHorizontalScrollIndicator={false}
scrollEventThrottle={10}
pagingEnabled
onScroll={
Animated.event(
[{nativeEvent: {contentOffset: {x: this.animVal}}}]
)
}
>
{imageArray}
</ScrollView>
<View style={styles.listViewContainer}>
<TouchableOpacity style={styles.listView} onPress={() => Actions.pop()}>
<View style={{flex: 1, flexBasis: 22}}>{listIcon}</View>
<View style={{flex: 2, flexBasis: 57}}><Text style={{color: '#fff'}}>List View</Text></View>
</TouchableOpacity>
</View>
<View style={styles.circleContainer}>
{circleArray}
</View>
</View>
<View style={styles.productsSection}>
<Text style={styles.title}>{prodDesc}</Text>
<Text style={styles.desc}>{prodBrand}</Text>
<Text style={styles.desc}>Item: {prodId || ''}</Text>
<Text style={[styles.desc, {marginBottom: 15}]}>Category: {prodCat}</Text>
<Table borderStyle={{borderWidth: 0}}>
<Rows data={rows}/>
</Table>
</View>
<View style={styles.bodyFooter}>
<QuantityCounter style={{width: '100%', display: 'block', marginRight: 20}} data={{productId: prodId}} />
</View>
</View>
</View>
<View style={styles.footer}>
<View style={styles.cartContainer}>
{cartIcon}
<Text style={{color: '#3A3A3A', fontSize: 14}}>18 items</Text>
</View>
<TouchableOpacity style={styles.viewCartButtonContainer} onPress={() => this.cartRedirect() }>
<Text style={{color: '#fff', fontSize: 15, marginTop: '5%'}}>View Cart</Text>
</TouchableOpacity>
</View>
<Header/>
</View >
);
here are my main styles for this:
var styles = StyleSheet.create({
wrapper: {
backgroundColor: '#E6E6E6',
marginVertical: 15,
marginHorizontal: 10,
borderRadius: 7,
elevation: 3,
maxHeight: '80%',
flexShrink: 1,
zIndex: 0,
marginTop: 75
},
container: {
flex: 1.7,
justifyContent: 'space-between',
alignItems: 'center',
height: '50%',
borderRadius: 7
},
footer: {
justifyContent:'space-between',
alignItems: 'center',
height: '10%',
backgroundColor: '#E6E6E6',
paddingVertical: 15,
paddingHorizontal: 17,
flexDirection: 'row',
borderStyle: 'solid',
borderTopColor: '#8E8E93',
borderTopWidth: 1
},
cartContainer: {
flexDirection: 'row',
width: '35%'
},
viewCartButtonContainer: {
backgroundColor: '#356FAF',
height: '90%',
width: '45%',
padding: 20,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 3
},
bodyFooter: {
backgroundColor: '#F6F6F6',
justifyContent: 'center',
flex: 0.45,
borderTopColor: '#D6D6D6',
borderTopWidth: 1,
borderStyle: 'solid',
borderBottomRightRadius: 7,
borderBottomLeftRadius: 7
},
circleContainer: {
position: 'absolute',
zIndex: 2,
bottom: 10,
left: 10,
flexDirection: 'row',
},
listViewContainer: {
position: 'absolute',
zIndex: 10,
top: 0,
right: 0,
justifyContent: 'center'
},
listView: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderTopRightRadius: 3,
backgroundColor: '#000',
paddingVertical: 5,
paddingHorizontal: 10
},
What it looks like without the keyboard:
What it looks like with the keyboard:
Handling View behavior when toggling a keyboard can be a tricky thing in React Native. There are multiple possible solutions to questions like this, but in this case the solution was this:
Instead of using style={{height:'100%'}} on your components that get pushed up, try using Dimensions:
import {Dimensions} from 'react-native';
const { height } = Dimensions.get('window');
and specify style={{ height }} in the right components.
Another thing that might be worth a try if someone else stumbles on this question:
React Native for Android has some default settings defined in the Android manifest. If you are not using Expo (or CRNA), you can change the behavior of the keyboard in AndroidManifest.xml by changing the windowSoftInputMode rule.
Try changing android:windowSoftInputMode="adjustResize" to android:windowSoftInputMode="adjustPan" or to android:windowSoftInputMode="adjustNothing". You can try to play around with some other options (See here) if this doesn't give you the desired effect.
You should use try behavior as "none" for android and if you don't want to getting small, you can set android:windowSoftInputMode="adjustPan" in manifest file.
and if still face any error checkout react-native-keyboard-aware-scrollview
here on npm.
I went through a similar problem and solved it by changing
android:windowSoftInputMode="adjustPanā€¯
In android manifest.
Also clean and rebuild. This might work
remove the position absolute it will works just fine trust me
for some cases if you want keep defualt manifest
you can move your elements inside a Scrollview it may help.
issue solved for me in this way

Resources