React-Native: Reverse zIndex in FlatList - android

I have a FlatList with some elements where the top element should overlap the bottom element. For this, I wanted to reverse the zIndex, but the FlatList keeps overwriting my zIndex.
In the code below I tried to reverse the zIndex with zIndex: 0 - index but it doesn't work
import React, { Component } from "react";
import { FlatList, Text, View, StyleSheet } from "react-native";
export default class App extends React.Component {
_renderPost({ index }) {
return <View style={[styles.item, { zIndex: 0 - index, }]} />;
}
render() {
return <FlatList data={[1, 2, 3, 4, 5,]} renderItem={this._renderPost} />;
}
}
const styles = StyleSheet.create({
item: {
height: 200,
borderWidth:2,
borderBottomLeftRadius:50,
borderBottomRightRadius:50,
marginBottom: -50,
backgroundColor:"white",
},
});
link to Expo Snack

I haven't managed to do it with the help of zIndex, since the Problem seems to be setting zIndex from the index, it just doesn't seem to work.
The way I managed to do it, would be by inverting the FlatList, and using a style for inverted column flex direction so that it actually is scrolled to the top as well. Do note that this would effectively also display the Posts in reverse order, so flipping the underlying arrays would be necessary to achieve the wanted results
import React, { Component } from "react";
import { FlatList, Text, View, StyleSheet } from "react-native";
export default class App extends React.Component {
_renderPost({ index }) {
return <View style={styles.item} />;
}
render() {
return <FlatList style={styles.container} inverted data={[1, 2, 3, 4, 5,]} renderItem={this._renderPost}/>;
}
}
const styles = StyleSheet.create({
item: {
height: 200,
borderWidth:2,
borderBottomLeftRadius:50,
borderBottomRightRadius:50,
marginBottom: -50,
backgroundColor:"white",
},
container: {
flexDirection: 'column-reverse'
}
});

Related

CodeWithMosh: building the listing screen Padding problem with iOS and Android not outputting the same result

In his video, in the last part, he says that at the time of his Recording in iOS the padding is not applying when he applies it in the Screen component, but it actually works on Android. And at the end, when you do exactly what he suggests, a double layer of padding is added in the Android version.
import React from 'react';
import { View, SafeAreaView, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
function SafeScreen({children, style}) {
return (
<SafeAreaView style={[styles.screen, style]}>
<View style={style}>{children}</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: {
paddingTop: Constants.statusBarHeight,
flex: 1,
}
})
export default SafeScreen;
I did find the Fix myself so look at my answer.
Here is the Fix that I did:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
function SafeScreen({children, style}) {
return (
<View style={[styles.screen ,style]}>{children}</View>
);
}
const styles = StyleSheet.create({
screen: {
paddingTop: Constants.statusBarHeight,
flex: 1,
},
})
export default SafeScreen;
Just simply don't use the SafeAreaView by React Native and instead apply the screen styling to the View.

React native maps showsMyLocationButton position

I am using Expo react-native-app. I have some local data which I want show in maps. For maps I have used React-native-maps. I successfully pull the data and display in maps by using Marker. For user location I have used expo-location and expo-permission. That works fine. I have used React-native-maps one props called showsMyLocationButton, by default props boolean false. when I made it true I can able to see in IOS Emulator and i think by default position bottom-right. Android emulator I don't see the button at all. This is ios image and this android image. I want to display some data under the maps like a Bottom-Sheet, for that I have used this package. As a result it hide the ios' showsMyLocationButton.
I want to display the user current location Button like Uber. I tried lots of way to do that but could not able to achieve the goal. I want change the button icon as well but also failed. Really appreciate if someone Help me out.
I shared my code in Snack Ps. it only works in ios and Android, does not work in web View.
This is my code
import React, { useState, useEffect, useCallback } from 'react';
import {
Dimensions, StatusBar, StyleSheet, Text,
TextInput, TouchableOpacity, View, Button
} from 'react-native';
import Constants from 'expo-constants';
import Mapview, { Marker, Callout, PROVIDER_GOOGLE } from 'react-native-maps'
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';
import datas from './datas.json'
// You can import from local files
import Animated from 'react-native-reanimated';
import BottomSheet from 'reanimated-bottom-sheet';
// or any pure javascript modules available in npm
export default function App() {
const sheetRef = React.useRef(null);
const renderContent = () => (
<View
style={{
backgroundColor: 'white',
padding: 16,
height: 450,
}}
>
<Text>Swipe down to close</Text>
<Button
title="Open Bottom Sheet"
onPress={() => sheetRef.current.snapTo(0)}
/>
</View>
);
const [state, setstate] = useState({
"latitude": 60.1098678,
"longitude": 24.7385084,
"latitudeDelta": 1,
"longitudeDelta": 1
});
useEffect(() => {
_onMapReady();
}, [_onMapReady]);
const _onMapReady = useCallback(async () => {
const { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== `granted`) {
// console.log(`Permisson Denied`);
}
const location = await Location.getCurrentPositionAsync({ "accuracy": Location.Accuracy.High });
setstate({
...state,
"latitude": location.coords.latitude,
"longitude": location.coords.longitude
});
}, [state]);
return (
<View style={styles.container}>
<Mapview
provider={PROVIDER_GOOGLE}
initialRegion={state}
showsIndoors={true}
showsMyLocationButton={true}
zoomControlEnabled={true}
zoomEnabled={true}
zoomTapEnabled={true}
showsScale={true}
showsBuildings={true}
showsUserLocation={true}
showsCompass={true}
onMapReady={_onMapReady}
style={styles.mapStyle}>
{
datas.data?.map((i) => {
return (
<Marker
coordinate={{
"latitude": i.location.lat,
"longitude": i.location.lng
}}
animation={true}
key={i.id}
>
<Callout
style={{ "width": 100, "height": 50 }}>
<View>
<Text>{i.Property}</Text>
</View>
</Callout>
</Marker>
);
})
}
</Mapview>
<BottomSheet
ref={sheetRef}
snapPoints={[450, 300, 0]}
borderRadius={10}
renderContent={renderContent}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
"flex": 1,
"alignItems": `center`,
"justifyContent": `center`
// position: 'absolute',
},
mapStyle: {
"height": Dimensions.get(`window`).height,
"width": Dimensions.get(`window`).width
},
});

React navigation header title cut off

So basically i'm in the process of learning react native. I'm using the react navigation package and I just want to display a simple header title on my stack navigator but the title cuts off. Stack nav title
This is my App.js
import React from 'react';
import { View, Text } from 'react-native';
import { createStackNavigator, createAppContainer} from 'react-navigation'
import HomeScreen from './screens/HomeScreen'
import DetailsScreen from './screens/DetailsScreen'
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home'
}
);
const AppContainer = createAppContainer(RootStack)
export default class App extends React.Component {
render(){
return<AppContainer />
}
}
and this is my HomeScreen.js
import React from 'react'
import {Button, View, Text } from 'react-native'
export default class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screeeen</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
)
}
}
It doesnt look like this on my friends phones. I'm using a OnePlus 6 with android 9. They are on older versions of android could that be causing something?
Turns out this is a specific problem affecting OnePlus user who has chosen to use the font OnePlus Slate instead of for exmaple robot. Changing the font in the phone fixes the problem, alternatively you force the usage of a font in the app and it should work as well
I got the same problem running on a OnePlus phone and solved it without the font loader but style with the navigation option in headerTitleStyle width like so:
import { Dimensions } from 'react-native';
const WIDTH = Dimensions.get('window').width;
export const MyStackNav = createStackNavigator(
{
Tab1: {
screen: Tab1,
navigationOptions: ({ navigation }) => ({
headerTitle: `${navigation.state.routeName} page`,
headerTitleStyle: {
width: WIDTH - 75,
},
}),
},
...more code
}
A similar issue also occurs in various components like button in one plus devices. One way to solve it by giving some minimum width to the label style, so that you don't have to switch the font family, helps if you are using some custom fonts
Solution: width: '100%' or some fixed value like minWidth: 100
Code example in drawer navigation
<DrawerItem
labelStyle={{ minWidth: 100 }}
label={`Orders`}
onPress={() => {}}
/>

Building a notification from a modal in React Navigation

I am attempting to build a notification service I can use within React Navigation; how far I have gotten in this:
Now this is a modal, that the card element has been hidden and then the view style has been filled into only 15% at the top of the element, and the element will react if you click out of the white area of the notification.
Here is the code for the NotificationModal:
import React from 'react';
import { View, TouchableHighlight,TouchableWithoutFeedback } from 'react-native';
import { Text } from 'react-native-elements';
export default class NotificationModal extends React.Component {
static navigationOptions = ({ navigation }) => {
const title = navigation.getParam('title','No item found...');
return {
title: title
};
};
constructor(props) {
super(props);
}
componentDidMount() {
console.log(this.props);
}
render() {
const { navigation } = this.props;
let title = navigation.getParam('title', '');
return (
<TouchableWithoutFeedback>
<View style={{ flex: 1 ,flexDirection: 'column', justifyContent: 'flex-start'}}>
<View style={{ height: "15%" ,width: '100%', backgroundColor:"#fff", justifyContent:"center"}}>
<Text style={{fontSize:25}}>{title}xd</Text>
</View>
<TouchableHighlight onPress={() => { this.props.navigation.goBack(); }} style={{backgroundColor: "rgba(0,0,0,0)"}}>
<View style={{ height: "85%" ,width: '100%', backgroundColor: "rgba(0,0,0,0)", justifyContent:"center"}}>
<View>
</View>
</View>
</TouchableHighlight>
</View>
</TouchableWithoutFeedback>
);
}
}
At at my root navigation stack it looks like this:
export default RootStack = createStackNavigator(
{
Main: {
screen: MainStack,
},
QuickStockModal: {
screen: StockModal,
},
NotificationModal: {
screen: NotificationModal,
}
},
{
mode: 'modal',
headerMode: 'none',
cardStyle:{
backgroundColor:"transparent",
opacity:0.99
}
}
);
Finally I call this pseudo notification modal like any other navigation instance:
this.props.navigation.navigate('NotificationModal', {
title: 'test'
});
Problems with this
It wont just act as a quick update, it will overtake the touch area, I just wish to let the user know things like 'search results empty' or 'barcode invalid' etc, without hijacking the touch. (But being able to touch buttons of the notification within the white area thats visible)
When you press the outside area to dismiss it, the 'dismiss area' turns dark as it disappears, this looks bad, I am hoping to change the animation to simply push up instead of down and hopefully avoid this
this is a messy way to do notifications but other manners will complicate my current app design too much (Using Redux for instance, will be alot of work for simply trying to add in-app notifications)
In-app notification libs arent customizable enough and also dont even work properly sadly

How to make a react native input which gives validation state feedback to the user. [Valid, Printine, Error, Editing]

I would like to have an input that updates continuously as the user types and then loses focus. The feedback will be a border around the input.
1 Green: when valid
2 Amber: when typing and is in error state (Green when valid)
3 Red: when in error state and unfocused
4 Nothing: when input is pristine (not touched and empty)
What is the best way to achieve this?
Ideally this will work with both iOS and Android.
TextInput has two functions that will be useful to achieve this:
onBlur and onChangeText
To dynamically set the style on the TextInput, you could attach a variable for the bordercolor like below:
<TextInput
onBlur={ () => this.onBlur() }
onChangeText={ (text) => this.onChange(text) }
style={{ borderColor: this.state.inputBorder, height: 70, backgroundColor: "#ededed", borderWidth: 1 }} />
Then, pass the result from the onChangeText function through a regex or pattern matcher to achieve whatever result you are trying to achieve.
I've set up a working project here that checks if there is whitespace, and throws the errors you are wanting. You can take it and edit it to be more specific to your needs, but the basic premise should work the same. I've also put the code below for the working project that implements the functionality:
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TextInput
} = React;
var SampleApp = React.createClass({
getInitialState: function() {
return {
inputBorder: '#eded',
defaultVal: ''
}
},
onBlur: function() {
console.log('this.state.defaultVal', this.state.defaultVal)
if(this.state.defaultVal.indexOf(' ') >= 0) {
this.setState({
inputBorder: 'red'
})
}
},
onChange: function(text) {
this.setState({
defaultVal: text
})
if(text.indexOf(' ') >= 0) {
this.setState({
inputBorder: '##FFC200'
})
} else {
this.setState({
inputBorder: 'green'
})
}
},
render: function() {
return (
<View style={styles.container}>
<View style={{marginTop:100}}>
<TextInput
onBlur={ () => this.onBlur() }
onChangeText={ (text) => this.onChange(text) }
style={{ height: 70, backgroundColor: "#ededed", borderWidth: 1, borderColor: this.state.inputBorder }} />
</View>
<View style={{marginTop:30}}>
<TextInput
style={{ height: 70, backgroundColor: "#ededed" }} />
</View>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);

Categories

Resources