React Native: Sidebar is shown but unable to interact with it - react-native

I am using React Native Sidebar
This is the sidebar:
<Sidebar
ref={(ref) => this._drawer = ref}
leftSidebar={ this.renderLeftSidebar() }
leftSidebarWidth = {200}
>
</Sidebar>
This is how I'm rendering the left sidebar:
renderLeftSidebar = () =>{
return (
<View style = {{ position:'absolute', backgroundColor:'#24292e4f', height:Dimensions.get('window').height}}>
<DrawerContent/>
</View>
)
}
And this is the content for that left sidebar:
export default DrawerContent = () => {
return (
<View style={styles.animatedBox}>
<Image
source={require('../assets/images/header.png')}
style={{height:200, alignSelf:'center'}}
/>
<View style = {styles.drawerContentView}>
<Icon
name='setting'
type='antdesign'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
onPress={() => console.log('hello settings')}
/>
</View>
The sidebar opens just fine and renders correctly, but when I try and press anything on the sidebar the press goes through the sidebar and interacts with elements rendered beneath it. Should I be using zIndex in my styles or is my approach completely wrong?

If you are using React-native-vector-icons, the ICON itself has no button properties.
You can use Icon.Button
import Icon from 'react-native-vector-icons/AntDesign';
...
<Icon.Button
name='setting'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
onPress={() => console.log('hello settings')}
>
This is Setting
</Icon.Button>
OR You can use TouchableOpacity
import {
TouchableOpacity
} from 'react-native'
import Icon from 'react-native-vector-icons/AntDesign';
...
<TouchableOpacity onPress={() => console.log('hello settings')}>
<Icon
name='setting'
color='#4abce3'
size ={22}
iconStyle = {styles.drawerItemIconStyle}
/>
</TouchableOpacity>

Related

React Native - Variable link using a prop

I'm making an app with some products that I got from my Wordpress database. On the homescreen, I have an overview of all the products, each in a tile. I want to be able to put a button in each tile, which links to the specific product page. But, since it works with a component, I need to be able to do this with a prop. And, if possible, based on the title of the API.
This is my code for the screen with all the products:
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, FlatList, Image, Button } from 'react-native';
import SuitcaseItem from '../components/SuitcaseItem';
const AllSuitcasesScreen = ({ navigation }) => {
const [suitcases, setSuitcases] = useState([]);
const getSuitcases = async () => {
try {
const response = await fetch("https://evivermeeren.com/wp-json/wp/v2/posts?categories=59", {
}
)
const json = await response.json();
console.log(json);
setSuitcases(json);
} catch (error) {
console.error(error);
}
}
useEffect(() => {
getSuitcases();
}, []);
return (
<View style={styles.screen}>
<View style={styles.flexbox2}>
<Text style={styles.products}>Onze koffers</Text>
<View style={styles.shoppingcart}>
<Image
style={styles.icon}
source={{uri: 'https://cdn-icons-png.flaticon.com/512/1413/1413908.png'}}
/>
<Text style={styles.number}>0</Text>
</View>
</View>
<View style={styles.list}>
<FlatList
data={suitcases}
renderItem={({ item }) => (
<SuitcaseItem
title={item.title.rendered}
imageUri={{uri: 'https://www.samsonite.be/on/demandware.static/-/Sites/default/dw851ab6f0/images/misc/sams_share-image.jpg'}}
desc={item.slug}
buttonText={item.title.rendered}
/>
)}
/>
</View>
</View>
);
}
export default AllSuitcasesScreen;
And this is the result:
Now, when I click the black button, I go to the page 'Evo L', which I also made. This is the button that I use:
<Pressable style={styles.seeProduct} onPress={() => navigation.navigate("Evo L")}>
<Text style={styles.text}>Bekijk product: {props.buttonText}</Text>
</Pressable>
This is in another file, the 'SuitcaseItem'.
So, I should be able to put something like navigation.navigate("props.buttonNav") with buttonNav = {item.title.rendered} so it goes to the page Evo L if I click on that one and then Evo M when I click on that tile and so one. Does anyone have an idea?
You can pass props to a screen. See this excellent official documentation for React Navigation on passing props.
-> Make a generic item detail screen like ItemDetail (instead of Evo L).
-> Modify the navigation.navigate("props.buttonNav") to:
navigation.navigate("ItemDetail", {itemTitle: props.buttonText})
You can access these props in the ItemDetail screen as:
function ItemDetail({ navigation, route }) {
return(
<Text>route.params.itemTitle</Text>
)
}

How can I link the button outside flatlit to hide and show the items inside the flatlist in each section react native

I am using flatlist in my app to show the result of the game by using API, I have a button outside the flatlist, I want the user to click the button and by clicking the button toggle switch will appear with each game and a user can switch off to hide the games and switch on to show the games.
First problem how can I link the button with the render function of flatlist to show the toggle switch.
Seconde is that how can I use the toggle switch to show and hide the games in flatlist.
<View style={{flex:1,}}>
<TouchableOpacity onPress={this.renderItem }> // What should I do here?
<Text style={{fontSize:30,color:'blue'}}>show/hide</Text>
</TouchableOpacity>
<DraggableFlatList
data={this.state.dataSource}
onDragEnd={this.dataSource}
renderItem={this.renderItem}
keyExtractor={item => item.GameId.toString()}
ItemSeparatorComponent={this.renderSeprator}
refreshing = {this.state.refreshing}
onRefresh = {this.handleRefresh}
/>
renderItem=({item,navigation,drag,btnvalue1})=>{
const current = new Date();
const currentHour = current.getHours();
return(
<ScaleDecorator>
<TouchableOpacity style={styles.item}
onLongPress={drag}
onPress={
() => this.props.navigation.navigate('ResultsStack',
{ screen: 'Result', params: { resultDate: this.state.resultDate ,GameId: item.GameId } }
//() => this.props.navigation.navigate('ResultsStack', { screen: 'Result' }
)} >
<Image style={styles.img}
source={{
uri: item.ImgUrl,
}}
/>
<Text style={styles.title}>{item.GameDescp} [{item.DrawRef}] [{item.DayName?.slice(0, 3)}]</Text>
<Text style={styles.txt3}>{item.Result03}</Text>
**//On click I want to hide this Ionicon and show a toggle switch**
<Ionicons
name="chevron-forward-outline"
style={styles.iconarrow}
//color={color}
size={30}
></Ionicons>
{this.btnvalue1 === 1 ? (
<Switch
style={styles.iconarrow}
trackColor={{ false: "#767577", true: "#81b0ff" }}
ios_backgroundColor="#3e3e3e"
/>) : null}
</TouchableOpacity>
</ScaleDecorator>

How to implement onPress in menu.item? native-base#3.2.1-rc.1

For some reason there's no nativeBase api or documentation on this. I can not get a menu.item to respond to press/click no matter what I try.
Attempts
putting Text/Button elements from react-native into the menu. item
putting the menu in multiple different screens
creating a separate function instead of just arrow function
import React from "react"
import {
Menu,
HamburgerIcon,
Box,
Center,
NativeBaseProvider,
usePropsResolution,
Text,
Pressable
} from "native-base"
import {Alert, } from "react-native";
import { logout } from "../_redux/_actions/authentication.actions";
export const NavMenu = (props) => {
const menuItems = ['Profile','Sign Out'];
return (
<Box h="80%" w="95%" alignItems="flex-start">
<Menu w="150" top="-85" h="100%"
trigger={(triggerProps) => {
return (
<Pressable accessibilityLabel="More options menu" {...triggerProps}>
<HamburgerIcon color="black" />
</Pressable>
)
}}
>
**<Menu.Item onPress={()=>alert("Alert Title")}>**
Logout
</Menu.Item>
</Menu>
</Box>
)
}
export default () => {
return (
<NativeBaseProvider>
<Center flex={1} px="1">
<NavMenu />
</Center>
</NativeBaseProvider>
)
}
I found workaround around this problem. Would be interested in better solution, but this should work (it is also not very clean solution):
<Menu.Item onPress={()=>alert("Alert Title")}>
<Pressable onPress={()=>alert("Alert Title")}><Text>Logout</Text></Pressable>
</Menu.Item>
Basically what I am doing here is putting onPress to the Menu.Item and then same onPress to the child. You can use this approach for more complicated situations like adding button to the menu like this:
<Menu.Group title="Účet">
<Menu.Item onPress={() => console.log('log')}>
<Button colorScheme="red" onPress={() => console.log('log')} leftIcon={<Icon size="s" as={<MaterialIcons name='logout' />} />}>
Logout
</Button>
</Menu.Item>
</Menu.Group>

React Native - trigger scrolling of FlatList outside the FlatList

I have a vertical FlatList component and two buttons as TouchableOpacity, how do I perform scrolling of the FlatList with the buttons,
i.e. 'scrolling the FlatList towards bottom` and 'scroll the FlatList towards top'?
Minimal Example:
<View>
<FlatList/>
<TouchableOpacity>
<Text>Scroll towards Top</>Text
</TouchableOpacity>
<TouchableOpacity>
<Text>Scroll towards Bottom</>Text
</TouchableOpacity>
</View>
This is not difficult to accomplish, The <Flatlist/> component already have methods to do that.
scrollToEnd(): Scrolls to the end of the content.
scrollToIndex(): Scrolls to the item at the specified index such 0 which is the top.
I have created a simple demo for you: https://snack.expo.io/#abranhe/flatlist-scroll
I have created a custom <Button/> and <Card/> components. I am creating an array with some random data with this format
const data = [
{ message: 'Random Message' }, { message: 'Random Message' }
]
I am adding a reference to the <Flatlist/> by adding
ref={ref => (this.flatlist = ref)}
Then I call the methods and that's it.
<Button title="▼" onPress={() => this.flatlist.scrollToEnd()} />
The whole source code:
import React from 'react';
import { Text, View, FlatList, StyleSheet } from 'react-native';
import { random } from 'merry-christmas';
import Card from './components/Card';
import Button from './components/Button';
const data = [...Array(10)].map(i => ({ message: random() }));
export default () => (
<View style={styles.container}>
<FlatList
ref={ref => (this.flatlist = ref)}
data={data}
renderItem={({ item }) => <Card gretting={item.message} />}
/>
<View style={styles.bottomContainer}>
<Button
title="▲"
onPress={() => this.flatlist.scrollToIndex({ index: 0 })}
/>
<Button title="▼" onPress={() => this.flatlist.scrollToEnd()} />
</View>
</View>
);
You can use a scrollView component

Click listener in flatlist

How can I add click listener in Flatlist?
My code:
renderItem({item, index}){
return <View style = {{
flex:1,
margin: 5,
minWidth: 170,
maxWidth: 223,
height: 304,
maxHeight: 304,
backgroundColor: '#ccc',
}}/>
}
render(){
return(<FlatList
contentContainerStyle={styles.list}
data={[{key: 'a'}, {key: 'b'},{key:'c'}]}
renderItem={this.renderItem}
/>);
}
}
Update 1: I used button but it is not working in Flatlist. However using only button instead of Flatlist, it works. Why is it not working in Flatlist renderItem?
_listener = () => {
alert("clicked");
}
renderItem({item, index}){
return<View>
<Button
title = "Button"
color = "#ccc"
onPress={this._listener}
/>
</View>
}
I used TouchableWithoutFeedback. For that, you need to add all the renderItem elements (i.e your row) into the TouchableWithoutFeedback. Then add the onPress event and pass the FaltList item to the onPress event.
import {View, FlatList, Text, TouchableWithoutFeedback} from 'react-native';
render() {
return (
<FlatList style={styles.list}
data={this.state.data}
renderItem={({item}) => (
<TouchableWithoutFeedback onPress={ () => this.actionOnRow(item)}>
<View>
<Text>ID: {item.id}</Text>
<Text>Title: {item.title}</Text>
</View>
</TouchableWithoutFeedback>
)}
/>
);
}
actionOnRow(item) {
console.log('Selected Item :',item);
}
You need to wrap your row element (inside your renderItem method) inside <TouchableWithoutFeedback> tag. TouchableWithoutFeedback takes onPress as it's prop where you can provide onPress event.
For TouchableWithoutFeedback refer this link
I used TouchableOpacity. and it's working great.This will give you click feedback. which will not be provided by TouchableWithoutFeedback. I did the following:
import { View, Text, TouchableOpacity } from "react-native";
.
.
.
_onPress = () => {
// your code on item press
};
render() {
<TouchableOpacity onPress={this._onPress}>
<View>
<Text>List item text</Text>
</View>
</TouchableOpacity>
}
If you are facing flatlist row first click issue
please add below property to flatlist.
disableScrollViewPanResponder = {true}
The Pressable component is now preferred over TouchableWithoutFeedback (and TouchableOpacity). According to the React Native docs for TouchableWithoutFeedback:
If you're looking for a more extensive and future-proof way to handle touch-based input, check out the Pressable API.
Example implementation:
import { Pressable } from "react-native";
render() {
return(
<FlatList
contentContainerStyle={styles.list}
data={[{key: 'a'}, {key: 'b'}, {key:'c'}]}
renderItem={({item}) => (
<Pressable onPress={this._listener}>
// BUILD VIEW HERE, e.g. this.renderItem(item)
</Pressable>
)}
/>
);
}
References
TouchableWithoutFeedback (React Native): https://reactnative.dev/docs/touchablewithoutfeedback
Pressable (React Native): https://reactnative.dev/docs/pressable
you dont need to add Touchable related component into your Flatlist renderItem. Just pass onTouchStart prop to your Flatlist.
in example:
<FlatList
style={themedStyles.flatListContainer}
data={translations}
renderItem={renderItem}
keyExtractor={(item, index) => `${item.originalText}____${index}`}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
ListEmptyComponent={renderEmptyListComponent}
onTouchStart={onBackgroundPressed}
/>