Issue with Flexbox content in Row, for React Native - css

I'm having some issues with FlexBox of an Item in React Native my wish is to have a table using a row with this look:
(Sorry for my poor Paint Skills but all the text Name and numbers should be center vertical and Horizontally)
How it Currently looks:
Now the issue is that as you can see the image gets out of the Card Look and also it is not complete from the Sides.
Also there are other team Data which the images are bigger or the names are bigger and therefore the images is even further to the left :S
Example:
Finally here is the Code of the Item where I create the Row:
import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import Card from '../UI/Card';
import Colors from '../../constants/Colors';
const TablaItem = props => {
return (
<Card style={styles.product}>
<View style={styles.touchable}>
<View style={styles.container}>
<View style={styles.flexItem}>
<View style={styles.imageContainer}>
<Image style={styles.image} source={{ uri: props.image}} />
</View>
</View>
<View style={styles.flexItem}>
<Text>{props.name}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.games}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.win}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.draw}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.loose}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.infavor}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.against}</Text>
</View>
<View style={styles.flexItem}>
<Text>{props.points}</Text>
</View>
</View>
</View>
</Card>
);
};
const styles = StyleSheet.create({
product: {
height: 50,
margin: 20,
justifyContent: 'center',
alignItems: 'center'
},
container: {
flex: 5,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
flexWrap: 'nowrap'
},
flexItem: {
flexGrow: 0,
flexShrink: 1,
flexBasis: 'auto',
alignSelf:'auto',
marginHorizontal: 10,
},
imageContainer: {
alignSelf: 'flex-end',
width: '200%',
height: '100%',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
marginHorizontal: 10,
},
image: {
width: '100%',
height: '100%'
},
});
export default TablaItem;
And Here the code of the page where I render those items in a FlatList:
import React, { useState, useEffect, useCallback } from 'react';
import { FlatList, Button, ActivityIndicator, View, StyleSheet, Text } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import * as tablaActions from '../store/actions/tabla';
import Colors from '../constants/Colors';
import Tabla from '../components/tablas/TablaItem';
import Encabezado from '../components/tablas/TablaEncabecado';
const TablaScreen = props => {
const [isLoading, setIsLoading] = useState(false);
const [isRefreshing, setIsRefreshing] = useState(false);
const [error, setError] = useState();
const tabla1 = useSelector(state => state.tabla.tabla1);
const tabla2 = useSelector(state => state.tabla.tabla2);
const dispatch = useDispatch();
//Aqui se llama a Load Tabla para llamar partidos desde el API
const loadTablas = useCallback(async () => {
setError(null);
setIsRefreshing(true);
try {
await dispatch(tablaActions.fetchTabla());
} catch (err) {
setError(err.message);
}
setIsRefreshing(false);
}, [dispatch, setIsLoading, setError]);
//unsuscribe de Tablas
useEffect(() => {
const unsubscribeTablas = props.navigation.addListener('focus', loadTablas);
return () => {
unsubscribeTablas();
};
}, [loadTablas]);
//useEffect (carga inicial) de Tablas
useEffect(() => {
setIsLoading(true);
loadTablas().then(() => {
setIsLoading(false);
});
}, [dispatch, loadTablas]);
if (error) {
return <View style={styles.centered} >
<Text>Ah Ocurrido un Error {error}</Text>
<Button title='Probar de Nuevo' onPress={loadTablas} color={Colors.secondary} />
</View>
}
if (isLoading) {
return <View style={styles.centered} >
<ActivityIndicator size='large' color={Colors.secondary} />
</View>
}
//Checkeo de Partidos no Vacio.
if (!isLoading && tabla1 === 0 || tabla2 === 0) {
return <View style={styles.centered} >
<ActivityIndicator size='large' color={Colors.secondary} />
</View>
}
return(
<>
<Text style={styles.grupo}>Grupo A</Text>
<FlatList
onRefresh={loadTablas}
refreshing={isRefreshing}
data={tabla1}
keyExtractor={item => item.teamId.toString()}
renderItem={
itemData => <Tabla
image={itemData.item.logo}
name={itemData.item.teamName}
games={itemData.item.matchsPlayed}
win={itemData.item.win}
draw={itemData.item.draw}
loose={itemData.item.lose}
infavor={itemData.item.goalsFor}
against={itemData.item.goalsAgainst}
points={itemData.item.points}
/>
}
/>
<Text style={styles.grupo}>Grupo B</Text>
<FlatList
onRefresh={loadTablas}
refreshing={isRefreshing}
data={tabla2}
keyExtractor={item => item.teamId.toString()}
renderItem={
itemData => <Tabla
image={itemData.item.logo}
name={itemData.item.teamName}
games={itemData.item.matchsPlayed}
win={itemData.item.win}
draw={itemData.item.draw}
loose={itemData.item.lose}
infavor={itemData.item.goalsFor}
against={itemData.item.goalsAgainst}
points={itemData.item.points}
/>
}
/>
</>
);
};
export const screenOptions = navData => {
return {
headerTitle: 'Tabla de Clasificacion',
// headerLeft: () => (<HeaderButtons HeaderButtonComponent={HeaderButton}>
// <Item
// title='Menu'
// iconName={Platform.OS === 'android' ? 'md-menu' : 'ios-menu'}
// onPress={() => {
// navData.navigation.toggleDrawer();
// }} />
// </HeaderButtons>),
// headerRight: () => (<HeaderButtons HeaderButtonComponent={HeaderButton}>
// <Item
// title='Carretilla'
// iconName={Platform.OS === 'android' ? 'md-cart' : 'ios-cart'}
// onPress={() => {
// navData.navigation.navigate('Cart');
// }} />
// </HeaderButtons>)
}
};
const styles = StyleSheet.create({
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
grupo: {
alignSelf: 'center',
fontWeight: 'bold',
fontSize: 16,
color: Colors.primary,
marginTop: 10,
}
});
export default TablaScreen;
I will also like to render the lines of the Flatlist one beneath the other with just a minimum gap currently it looks like this:
And will also like to add to the top something like this:
Which is basically a Header with the same style, and it will have the titles:
Equipo (which will be the length of the Image and Name), Juegos, Ganados, Empates, Perdidos, Afavor, Encontra, Puntos.
This Last part is just a wish to know.
Any Ideas?

Give your Image resizeMode of "contain" or "cover"
<Image
resizeMode="contain"
style={{ flex: 1 }}
source={{ uri: 'https://ezgif.com/images/insert-image.png' }}
/>
Working Example: Expo Snack
Sample Output:
Sample App Source Code:
import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import { Card } from 'react-native-paper';
export default TablaItem = (props) => {
return (
<View style={{ flex: 1, backgroundColor: '#212121' }}>
<View style={styles.card}>
<View>
<View style={styles.imageCircle}>
<Image
resizeMode="cover"
style={{ flex: 1 }}
source={{ uri: 'https://ezgif.com/images/insert-image.png' }}
/>
</View>
</View>
<View style={{ marginLeft: 10, flex: 2 }}>
<Text style={styles.text}>{'Alianza Alianza'}</Text>
</View>
<View
style={{
flexDirection: 'row',
flex: 7,
justifyContent: 'space-evenly',
}}>
<View>
<Text style={styles.text}>{10}</Text>
</View>
<View>
<Text style={styles.text}>{6}</Text>
</View>
<View>
<Text style={styles.text}>{4}</Text>
</View>
<View>
<Text style={styles.text}>{0}</Text>
</View>
<View>
<Text style={styles.text}>{15}</Text>
</View>
<View>
<Text style={styles.text}>{9}</Text>
</View>
<View>
<Text style={styles.text}>{20}</Text>
</View>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
imageCircle: {
width: 50,
height: 50,
backgroundColor: 'white',
borderRadius: 25,
padding: 8,
borderWidth: 2,
borderColor: 'rgba(21,21,21,0.2)',
justifyContent: 'center',
alignContent: 'center',
},
card: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: 'white',
borderRadius: 10,
margin: 10,
paddingHorizontal: 5,
padding: 2,
marginTop: 30,
},
text: {
fontSize: 14,
fontWeight: '600',
},
});

Related

React native checkbox paper not checking individually

I am currently building a todo list productivity application and using the checkboxes from https://callstack.github.io/react-native-paper/checkbox-item.html
Im looping through my users todos through firebase and added a checkbox for each. However, when they check it, all of the todos get checked, not the invididual one. What would be the solution?
Code:
import React, { useEffect } from 'react';
import {useState} from "react"
import { SafeAreaView, Text, View, Button, TouchableOpacity, Modal, StyleSheet,Pressable, TextInput,ImageBackground, Image, ScrollView, } from 'react-native';
import { collection, doc, setDoc, query, getDocs, onSnapshot, addDoc, orderBy, limit, Timestamp, where} from "firebase/firestore";
import {db} from "../firebase"
import { auth } from '../firebase';
import AsyncStorage from '#react-native-async-storage/async-storage';
import { AntDesign } from '#expo/vector-icons';
import { Feather } from '#expo/vector-icons';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Checkbox } from 'react-native-paper';
import {signPlsOut} from "../firebase"
export const Dashboard = () => {
const image = { uri: "https://cdn.discordapp.com/attachments/901614276748402820/946157600041476176/Screen_Shot_2022-02-23_at_4.32.16_PM.png" };
const {uid, photoURL, displayName} = auth.currentUser;
const projectsref = collection(db, "projects");
const [modalVisible, setModalVisible] = useState(false);
const [projects, setProjects] = useState([])
const [desc, setDesc] = useState("");
const [title, setTitle] = useState("");
const [checked, setChecked] = React.useState(false);
useEffect(() => {
const getData = async () => {
const q = await query(projectsref, where('uid', '==', uid), orderBy("createdAt"))
onSnapshot(q, (snapshot) => {
let todos = []
snapshot.forEach((doc) => {todos.push(doc.data())})
setProjects(todos)
})
}
getData()
}, [])
async function handleAddTask () {
try {
await addDoc(projectsref, {
title: title,
desc: desc,
createdAt: Timestamp.fromDate(new Date()),
uid: uid,
})
setTitle("")
setDesc("")
setModalVisible(false)
}
catch(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
// ADD THIS THROW error
throw error;
}
}
return (
<SafeAreaView style={{
flex: 1,
display: "flex",
justifyContent: 'space-between',
margin: 20,
flexDirection: "column",
}}>
<View style={{
flex: 1,
marginTop: 20
}}>
<View style={{marginBottom: 20, display: "flex", flexDirection: "row", justifyContent: "space-between"}}>
<View style={{display: "flex", flexDirection: "row"}}>
<Image source={{uri: "https://cdn.discordapp.com/attachments/856542608171073616/947245168191496212/Screen_Shot_2022-02-26_at_4.33.30_PM.png"}} style={{width: 50, height: 50}}></Image>
<View style={{marginLeft: 20, display: "flex", justifyContent: "space-between"}}>
<Text style={{fontSize: 17, fontWeight: "700"}}>{auth.currentUser.email}</Text>
<Text style={{color: "grey", fontSize: 15}}>Good Morning 👋🏼</Text>
</View>
</View>
<View style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
<AntDesign name="search1" size={24} color="black" />
<Feather name="bell" size={24} color="black" style={{marginLeft: 10}}/>
</View>
</View>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Add task:</Text>
<View style={{marginBottom: 20}}>
<TextInput placeholder='title' value={title} onChangeText={(text) => setTitle(text)} ></TextInput>
<TextInput placeholder='description' value={desc} onChangeText={(text) => setDesc(text)}></TextInput>
</View>
<Button title='submit todo' onPress={handleAddTask}></Button>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Cancel</Text>
</Pressable>
</View>
</View>
</Modal>
<ScrollView style={{backgroundColor: "#EEE6DF", flex: 1, padding: 10, borderRadius: 20, marginBottom: 20, }}>
<Text style={{
fontSize: 30,
fontWeight: "700"
}}>Create Daily Tasks 🙌</Text>
<View style={{display: "flex", flexDirection: "row", flexWrap: "wrap", alignItems: "center"}}>
{projects.map((doc, key) => (
<View key={key} style={{
backgroundColor: "#fff",
borderRadius: "20px",
padding: 10,
marginTop: 20,
width: 130,
marginLeft: 20
}}>
<Checkbox
status={checked ? 'checked' : 'unchecked'}
onPress={() => {
setChecked(!checked);
}}
/>
<Text style={{
color: "#000",
fontSize: 30,
fontWeight: "700"
}}>{doc.title}</Text>
<Text style={{
color: "#000",
fontSize: 20
}}>{doc.desc}</Text>
</View>
))}
<Button title='Sign Out' onPress={signPlsOut} style={{marginLeft: 100}}></Button>
</View>
</ScrollView>
</View>
<View style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
}}>
<TouchableOpacity >
<Pressable
onPress={() => setModalVisible(true)}>
<AntDesign name="pluscircle" size={50} color="#8BF45B" />
</Pressable>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
You must have a state for each ToDo separately.
For this, you can create an array state to store the id's wich ToDo are checked
const [checked, setChecked] = React.useState([]);
{projects.map((doc, key) => (
<View key={key} style={{
backgroundColor: "#fff",
borderRadius: "20px",
padding: 10,
marginTop: 20,
width: 130,
marginLeft: 20
}}>
<Checkbox
status={checked.find((item) => item === doc.id) ? 'checked' : 'unchecked'}
onPress={() => {
if(checked.find((item) => item === doc.id)) { //Verify if the ToDo id exist on checked state
setChecked(checked.filter((item) => item !== doc.id)); //Sets the checked state to an array without the current doc.id
} else {
setChecked([...checked, doc.id)] // add the current ToDo doc.id to the checked state
}
}}
/>
<Text style={{
color: "#000",
fontSize: 30,
fontWeight: "700"
}}>{doc.title}</Text>
<Text style={{
color: "#000",
fontSize: 20
}}>{doc.desc}</Text>
</View>
))}
This logic was the one I could think of now, I don't know if it is the best way but I hope it helps

Making a done button with expo checkbox with users todos via firstore/firebase

I am currently building a todo based applciation with expo, react native, and google firebase. When the user has logged in via email and wants to make a new todo by pressing the plus button. I want them to have the ability to check off their todo as done with a checkbox (using expo checkbox). However When i checkoff a certian todo, all the todos check off. What can i possibly do to make it unique to each todo (checkbox)?
import React, { useEffect } from 'react';
import {useState} from "react"
import { SafeAreaView, Text, View, Button, TouchableOpacity, Modal, StyleSheet,Pressable, TextInput,ImageBackground, Image, ScrollView, } from 'react-native';
import { collection, doc, setDoc, query, getDocs, onSnapshot, addDoc, orderBy, limit, Timestamp, where} from "firebase/firestore";
import {db} from "../firebase"
import { auth } from '../firebase';
import AsyncStorage from '#react-native-async-storage/async-storage';
import { AntDesign } from '#expo/vector-icons';
import { Feather } from '#expo/vector-icons';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import Checkbox from 'expo-checkbox';
import {signPlsOut} from "../firebase"
export const Dashboard = () => {
const image = { uri: "https://cdn.discordapp.com/attachments/901614276748402820/946157600041476176/Screen_Shot_2022-02-23_at_4.32.16_PM.png" };
const {uid, photoURL, displayName} = auth.currentUser;
const projectsref = collection(db, "projects");
const [modalVisible, setModalVisible] = useState([]);
const [projects, setProjects] = useState([])
const [desc, setDesc] = useState("");
const [title, setTitle] = useState("");
const [isChecked, setChecked] = React.useState(false)
useEffect(() => {
const getData = async () => {
const q = await query(projectsref, where('uid', '==', uid), orderBy("createdAt"))
onSnapshot(q, (snapshot) => {
let todos = []
snapshot.forEach((doc) => {todos.push(doc.data())})
setProjects(todos)
})
}
getData()
}, [])
async function handleAddTask () {
try {
await addDoc(projectsref, {
title: title,
desc: desc,
createdAt: Timestamp.fromDate(new Date()),
uid: uid,
})
setTitle("")
setDesc("")
setModalVisible(false)
}
catch(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
// ADD THIS THROW error
throw error;
}
}
return (
<SafeAreaView style={{
flex: 1,
display: "flex",
justifyContent: 'space-between',
margin: 20,
flexDirection: "column",
}}>
<View style={{
flex: 1,
marginTop: 20
}}>
<View style={{marginBottom: 20, display: "flex", flexDirection: "row", justifyContent: "space-between"}}>
<View style={{display: "flex", flexDirection: "row"}}>
<Image source={{uri: "https://cdn.discordapp.com/attachments/856542608171073616/947245168191496212/Screen_Shot_2022-02-26_at_4.33.30_PM.png"}} style={{width: 50, height: 50}}></Image>
<View style={{marginLeft: 20, display: "flex", justifyContent: "space-between"}}>
<Text style={{fontSize: 17, fontWeight: "700"}}>{auth.currentUser.email}</Text>
<Text style={{color: "grey", fontSize: 15}}>Good Morning 👋🏼</Text>
</View>
</View>
<View style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
<AntDesign name="search1" size={24} color="black" />
<Feather name="bell" size={24} color="black" style={{marginLeft: 10}}/>
</View>
</View>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Add task:</Text>
<View style={{marginBottom: 20}}>
<TextInput placeholder='title' value={title} onChangeText={(text) => setTitle(text)} ></TextInput>
<TextInput placeholder='description' value={desc} onChangeText={(text) => setDesc(text)}></TextInput>
</View>
<Button title='submit todo' onPress={handleAddTask}></Button>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Cancel</Text>
</Pressable>
</View>
</View>
</Modal>
<ScrollView style={{backgroundColor: "#EEE6DF", flex: 1, padding: 10, borderRadius: 20, marginBottom: 20, }}>
<Text style={{
fontSize: 30,
fontWeight: "700"
}}>Create Daily Tasks 🙌</Text>
<View style={{display: "flex", flexDirection: "row", flexWrap: "wrap", alignItems: "center"}}>
{projects.map((doc, key) => (
<View key={key} style={{
backgroundColor: "#fff",
borderRadius: "20px",
padding: 10,
marginTop: 20,
width: 130,
marginLeft: 20
}}>
<Checkbox
style={styles.checkbox}
value={isChecked}
onValueChange={setChecked}
color={isChecked ? '#4630EB' : undefined}
/>
<Text style={{
color: "#000",
fontSize: 30,
fontWeight: "700"
}}>{doc.title}</Text>
<Text style={{
color: "#000",
fontSize: 20
}}>{doc.desc}</Text>
</View>
))}
<Button title='Sign Out' onPress={signPlsOut} style={{marginLeft: 100}}></Button>
</View>
</ScrollView>
</View>
<View style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
}}>
<TouchableOpacity >
<Pressable
onPress={() => setModalVisible(true)}>
<AntDesign name="pluscircle" size={50} color="#8BF45B" />
</Pressable>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};

Absolute position in React-Native

Fix: My problem was that I didn't know what I should use. And this is which I want.
If you want to make it yourself, see ksav's answer
I have a component which acts as a Picker in React Native.
<Modal
transparent
visible={editVisible}
animationType="fade"
onRequestClose={modalChange}>
<Pressable style={styles.modalView} onPressOut={modalChange}>
<View style={styles.modalContainer}>
<TouchableOpacity style={styles.button} onPressOut={modalChange}>
<Text>Edit button</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPressOut={modalChange}>
<Text>Delete button</Text>
</TouchableOpacity>
</View>
</Pressable>
</Modal>
<TouchableOpacity onPress={modalChange}>
<Ionicons name="ios-ellipsis-horizontal-sharp" size={20} />
</TouchableOpacity>
I want to set the modalContainer to always be at the bottom of TouchableOpacity (Ionicons). But I set TouchableOpacity's css: position: 'relative' and
modalContainer: {
position: absolute,
bottom: 0,
right: 0,
}
It's not working as expected. Because:
position in React Native is similar to regular CSS, but everything is set to relative by default, so absolute positioning is always relative to the parent.
To simplify the problem, I want some View is always under the button which will show the view when I onPress
My demo
Ensure the parent View is flexing vertically and that your style is position: 'absolute',
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Modal, Pressable } from 'react-native';
export default function App() {
const [modalVisible, setModalVisible] = React.useState(false);
return (
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.modalContainer}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.textStyle}>Show Modal</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
modalContainer: {
position: 'absolute',
bottom: 0,
right: 0,
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22
},
modalView: {
margin: 20,
backgroundColor: "white",
borderRadius: 20,
padding: 35,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5
},
});
After discussion, I think what you want would better be described as a tooltip or a popover rather than modal. E.g it is positioned at the bottom of the button that opens it, but doesnt take up any space in the flow.
import * as React from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity,
Modal,
Pressable,
SafeAreaView,
} from 'react-native';
export default function App() {
const [tooltipVisible, settooltipVisible] = React.useState(false);
const [buttonHeight, setButtonHeight] = React.useState(0);
const handleLayout = (event) => {
const { x, y, height, width } = event.nativeEvent.layout;
setButtonHeight(height)
};
const handlePress = () => {
settooltipVisible(!tooltipVisible);
};
return (
<SafeAreaView style={styles.centeredView}>
<Pressable
onLayout={handleLayout}
style={[styles.button, styles.buttonOpen]}
onPress={() => settooltipVisible(true)}>
<Text style={styles.textStyle}>Show Thing</Text>
</Pressable>
{tooltipVisible && (
<View style={[styles.tooltipView, {top: buttonHeight}]}>
<Text style={styles.modalText}>Hello World!</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={handlePress}>
<Text style={styles.textStyle}>Hide Thing</Text>
</Pressable>
</View>
)}
<Text>Some other content</Text>
<Text>Some other content</Text>
<Text>Some other content</Text>
<Text>Some other content</Text>
<Text>Some other content</Text>
<Text>Some other content</Text>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
button: {
padding: 20,
backgroundColor: 'blue',
color: 'white',
},
centeredView: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 60,
},
tooltipView: {
zIndex:1,
padding: 20,
position: 'absolute',
backgroundColor: 'white',
borderRadius: 20,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
});
Demo

I have a Flatlist with positoin:absolute ,onpress inside the render item Not responding

Im building an autocomplete feature in react-native .
Here the problem is when i wrap the flatlist with styling position 'absolute' onpress not responding.
return ( <View style={styles.userNameSearchContainer}>{searchUserName()}</View>
<View style={styles.sendInviteContainer}>{sendInvite()}</View>)
const searchUserName = () => {
let searchUser = (
<KeyboardAvoidingView>
<View>
<Text style={styles.searhUserTitle}>Search by username</Text>
</View>
<View style={styles.searchUserInputWrapper}>
<Image
style={styles.searchIcon}
source={require("../../../assets/Images/search.png")}
/>
<TextInput
style={{ flex: 1 }}
placeholder={"#user114"}
value={searchText}
onChangeText={(text) => onSearchTextChanged(text)}
/>
</View>
<View>
<FlatList
style={{ position:'absolute', width: "100%" }}
data={filteredUsers}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
</KeyboardAvoidingView>
);
return searchUser;
};
const renderItem = ({ item }) => (
<TouchableOpacity onPress={(item) => console.log(item)}>
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
</View>
</TouchableOpacity> );
I have tried importing touchableOpacity from gesture-handler and touchablewithoutfeedback.
Heres is an example
snack: https://snack.expo.io/#ashwith00/ranting-bubblegum
import * as React from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
TextInput,
TouchableOpacity,
} from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const searchResult = ['data1', 'data2', 'data3', 'data4', 'data5'];
export default function App() {
const [str, setStr] = React.useState('');
return (
<View style={styles.container}>
<TextInput style={styles.input} onChangeText={(st) => setStr(st)} />
<View style={[styles.list, ]}>
{str.length > 0 && <FlatList
data={searchResult}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.item}
onPress={() => console.log(item)}>
<Text style={styles}>{item}</Text>
</TouchableOpacity>
)}
/>}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight || 10,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
input: {
alignSelf: 'stretch',
height: 50,
backgroundColor: 'white',
},
item: {
alignSelf: 'stretch',
justifyContent: 'center',
alignItems: 'center',
height: 50,
backgroundColor: 'white',
},
list: {
position: 'absolute',
top: 60,
left: 0,
right: 0,
paddingHorizontal: 10,
height: 200,
},
});

Flexbox in react native : How to align 2 items at the center of the screen?

I discovered flexbox recently and I'm struggling to make it work, I'm surely missed some concept that make me hard time to understands it's mechanics so here is what I have:
It's a preview camera screen
with a back button on the top right
A text in the middle
and a record button to shoot some images
Here is what I have at the moment:
this is done with this React native component (style included)
import React from "react";
import { RNCamera } from "react-native-camera";
import { StyleSheet, TouchableOpacity, View, Platform} from "react-native";
import {Icon, Text} from "native-base";
import RequestPermissions from "../components/Permissions/RequestPermissions";
import I18n from "../i18n/i18n";
/**
* This is the component which allows the user to film his own film
*/
export default class CameraScreen extends React.Component
{
constructor(props) {
super(props);
this.camera = null;
}
state = {
isRecording: false,
iconVid: "record",
iconMode: null,
overlay: true
};
/**
* With RNCamera, it seems that permission is always asked to the user... Maybe this code is then irrelevant
*/
componentWillMount() {
if (Platform.OS === "android") {
RequestPermissions().then(() => {
console.log("granted");
}).then((err) => {
console.log(err)
});
}
}
componentWillUnmount() {
this.stopRecording();
};
stopRecording = () => {
if (this.camera) {
this.camera.stopRecording();
this.setState({
isRecording: false,
iconVid: "record"
});
}
};
renderCamera = () => {
return (
<View style={styles.container}>
<RNCamera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
>
<View style={styles.controlsContainer}>
<View style={styles.topRightButton}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Icon name={"arrow-left"} type={"Feather"} style={styles.iconFurtive}/>
</TouchableOpacity>
</View>
<View style={styles.middleContainer}>
<Text style={styles.actionText}>{I18n.t("action_text").toUpperCase()}</Text>
</View>
<View style={styles.leftContainer}>
<TouchableOpacity onPress={() => this.recordVideo()}>
<Icon name={this.state.iconVid} type={"MaterialCommunityIcons"} style={styles.iconCamera}/>
</TouchableOpacity>
</View>
</View>
</RNCamera>
</View>
);
};
/**
* For more options
* https://github.com/react-native-community/react-native-camera/blob/master/docs/RNCamera.md#recordasyncoptions-promise
*/
recordVideo = () => {
if (this.camera) {
this.setState({ isRecording: true, iconVid: "stop" });
// Show the overlay
console.log("Device is Recording");
this.camera.recordAsync({maxDuration: 15}).then(data => {
this.stopRecording();
console.log("Stop Recording");
console.log(data);
}).catch((err) => {
console.log(err);
this.stopRecording();
});
}
};
render() {
return this.renderCamera()
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop:30,
},
controlsContainer: {
flex: 1,
flexDirection: "column"
},
topRightButton: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'flex-start',
},
middleContainer: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'center',
},
leftContainer: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'flex-end',
},
actionText: {
color: "#fff",
fontSize: 72
},
preview: {
flex: 1,
},
iconCamera: {
color: "#ff4459",
marginBottom: 50,
padding: 25,
backgroundColor: "#fff",
borderRadius: 50,
},
iconFurtive: {
color: "#fff",
marginTop: 50,
marginLeft: 50,
}
});
Here is what I want:
How to do that with flexbox? What am I missing?
Code changed at View with {styles.topRightButton}
return (
<View style={styles.container}>
<RNCamera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
>
<View style={styles.controlsContainer}>
<View style={{justifyContent: 'flex-start', alignItems: 'flex-start',}}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Icon name={"arrow-left"} type={"Feather"} style={styles.iconFurtive}/>
</TouchableOpacity>
</View>
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-around'}}>
<View style ={{height: 50, width: 50, backgroundColor: 'transparent'}} />
<Text style={styles.actionText}>{I18n.t("action_text").toUpperCase()}</Text>
<TouchableOpacity onPress={() => this.recordVideo()}>
<Icon name={this.state.iconVid} type={"MaterialCommunityIcons"}/>
</TouchableOpacity>
</View>
</View>
</RNCamera>
</View>
);
For middle and left the content should be in the same div with that div having a flexDrirection: 'row'. This puts them in the same row.
The controls container can have justifyContent: 'center', and alignItems: 'center'.
The topRightButton should override the parents style.

Resources