How to make a two column grid on react native? - react-native

I am tasked right now with making a screen that gives options in a grid of two columns with multiple cards as the items of a list. (You can see here)
I was trying to create a row flexbox, but it ended up simply continuing horizontally forever.
I'd like to know what would be a good way to get this effect os two columns expanding downwards.

You should use FlatList and set numColumns prop to "2" to show FlatList as grid
Here is complete code sample
import React from "react";
import { SafeAreaView, FlatList, Text, View, Image } from "react-native";
const DATA = [
{
id: "1",
title: "RUSTY DRIVE",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "2",
title: "SABOR MORENO",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "3",
title: "0 MESTRE PUB",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "4",
title: "GRILL 54 CHEF",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "5",
title: "RUSTY DRIVE",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "6",
title: "SABOR MORENO",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "7",
title: "0 MESTRE PUB",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
},
{
id: "8",
title: "GRILL 54 CHEF",
image:
"https://res.cloudinary.com/demo/image/upload/w_260,h_200,c_crop,g_north/sample.jpg"
}
];
export default class App extends React.Component {
_renderItem = ({ item }) => (
<View style={{ flex: 1, marginHorizontal: 20, marginBottom: 20 }}>
<Image
style={{ width: "100%", height: 140 }}
source={{ uri: item.image }}
/>
<Text style={{ textAlign: "center", marginTop: 8 }}>{item.title}</Text>
</View>
);
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={DATA}
renderItem={this._renderItem}
keyExtractor={item => item.id}
numColumns={2}
style={{ flex: 1 }}
contentContainerStyle={{ paddingVertical: 20 }}
/>
</SafeAreaView>
);
}
}
App Preview

You can achieve this by simply doing something like:
<View style={{flex:1, flexDirection:"row", maxHeight:100}}>
<View style={{flex : 1, backgroundColor:"red"}}/>
<View style={{flex : 1, backgroundColor:"yellow"}}/>
</View>
Then adding new views will let you achieve such a layout, then it's up to you deciding what and how many you want to render

Related

FlatList with ScrollTo in React Native

I'm new to React Native, I'm trying to make a FlatList in an application with Expo that will pull some categories of products from a Json, I managed to make the FlatList and also a Json simulation for testing, however I wish that by clicking on any item in the FlatList it directs the Scroll to the respective section, the same when using anchor with id in HTML.
For example: FlatList will display the categories: Combo, Side Dishes, Hot Dog, etc. For each category that is displayed by FlatList I have already created a View that will display products in this category.
What I want to do:
When you click on a category displayed by FlatList the Scroll scrolls to the View that displays the products of this category, that is, if you click on Combo the page scrolls to the View that displays the products of the Combo category, if you click on Side Dishes the page scrolls until the View that displays the products in the Side Dishes category, follows my code:
Follow my code: (it can be simulated here: https://snack.expo.io/#wendell_chrys/06944b)
import React, { useEffect, useState } from 'react';
import { View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity } from 'react-native';
import { AppLoading } from 'expo';
import Constants from 'expo-constants';
const DATA = [
{
id: "1",
title: "Combos",
categorie: "section1",
},
{
id: "2",
title: "Side Dishes",
categorie: "section2",
},
{
id: "3",
title: "Hot Dog",
categorie: "section3",
},
{
id: "4",
title: "Desserts",
categorie: "section4",
},
{
id: "5",
title: "Drinks",
categorie: "section5",
},
];
const renderItem = ({ item }) => {
return (
<Item
item={item}
/>
);
};
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} >
<Text style={styles.itenscategoria}>{item.title}</Text>
</TouchableOpacity>
);
export default function App() {
return (
<View style={styles.container}>
<View style={styles.categories}>
<FlatList
data={DATA}
horizontal
showsHorizontalScrollIndicator={false}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
<ScrollView>
<View style={styles.section1}>
<Text>Combos</Text>
</View>
<View style={styles.section2}>
<Text>Side Dishes</Text>
</View>
<View style={styles.section3}>
<Text>Hot Dog</Text>
</View>
<View style={styles.section4}>
<Text>Desserts</Text>
</View>
<View style={styles.section5}>
<Text>Drinks</Text>
</View>
</ ScrollView>
</View >
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#000',
padding: 8,
},
categories: {
backgroundColor: '#FFFFFF',
width: '100%',
height: 50,
top: 10,
marginBottom:20,
},
itenscategoria: {
padding:15,
border: 1,
borderRadius:25,
marginRight:10,
},
section1: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
section2: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
section3: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
section4: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
section5: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
});
You can make use of scrollToIndex of FlatList
See complete code below, or the snack here.
import React, { useEffect, useState, useRef } from 'react';
import { View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity } from 'react-native';
import { AppLoading } from 'expo';
import Constants from 'expo-constants';
const DATA = [
{
id: "1",
title: "Combos",
categorie: "section1",
},
{
id: "2",
title: "Side Dishes",
categorie: "section2",
},
{
id: "3",
title: "Hot Dog",
categorie: "section3",
},
{
id: "4",
title: "Desserts",
categorie: "section4",
},
{
id: "5",
title: "Drinks",
categorie: "section5",
},
];
export default function App() {
const flatListRef = useRef();
const handleItemPress = (index) => {
flatListRef.current.scrollToIndex({ animated: true, index });
};
const renderItem = ({ item, index }) => {
return (
<Item
item={item}
onPress={() => handleItemPress(index)}
/>
);
};
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} >
<Text style={styles.itenscategoria}>{item.title}</Text>
</TouchableOpacity>
);
const renderDetails = ({ item, index }) => (
<View style={styles.section}>
<Text>{item.title}</Text>
</View>
);
return (
<View style={styles.container}>
<View style={styles.categories}>
<FlatList
data={DATA}
horizontal
showsHorizontalScrollIndicator={false}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
<FlatList
ref={flatListRef}
data={DATA}
renderItem={renderDetails}
keyExtractor={(item) => item.id}
/>
</View >
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#000',
padding: 8,
},
categories: {
backgroundColor: '#FFFFFF',
width: '100%',
height: 50,
top: 10,
marginBottom:20,
},
itenscategoria: {
padding:15,
border: 1,
borderRadius:25,
marginRight:10,
},
section: {
marginTop: 10,
backgroundColor: '#ccc',
width: '100%',
height: 200,
borderRadius: 10,
},
});

React Native Flatlist can't see the bottom of the flatlist

I want to show a flatlist but I have a problem. In the bottom of the phone, I can't show the integrality of the post and don't scroll to it. I don't know why. Some issues ? I have try some spacing stuff with style but that's don't work like I want.
import React, { Component } from 'react'
import { View, Text, FlatList } from 'react-native'
import BlockPhoto from '../ui/BlockPhoto';
import { isTemplateElement } from '#babel/types';
interface Props { }
interface State { monTabPost: Array<TabPost> }
interface TabPost { id: number, title: string, }
const monTabPost: Array<TabPost> = [
{ id: 1, title: "Chat 1", },
{ id: 2, title: "Chat 2", },
{ id: 3, title: "Chat 3", },
{ id: 4, title: "Chat 4", },
{ id: 5, title: "Chat 5", },
{ id: 6, title: "Chat 6", },
{ id: 7, title: "Chat 7", },
{ id: 8, title: "Chat 8", },
]
export default class VueFlatList extends Component<Props, State> {
state = {
monTabPost: monTabPost ? monTabPost : []
}
render = () => {
return (
<View style={{ paddingHorizontal: 30 }}>
<Text style={{ paddingVertical: 20, backgroundColor: "black", marginBottom: 5, color: "white", textTransform: "uppercase", textAlign: "center", fontWeight: "bold" }}>Mon titre</Text>
<FlatList
//inverted
data={this.state.monTabPost}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) =>
<View>
<Text>Mon post</Text>
<BlockPhoto title={item.title} />
</View>
}
/>
</View>
)
}
}
Add contentContainerStyle={{ paddingBottom: 100 // <-- you can calibrate this }} on Flatlist component.
can replace your render to below it will work,
render = () => {
return (
<View style={{ paddingHorizontal: 30, flex: 1, width: '100%' }}>
<Text style={{ paddingVertical: 20, backgroundColor: "black", marginBottom: 5, color: "white", textTransform: "uppercase", textAlign: "center", fontWeight: "bold" }}>Mon titre</Text>
<FlatList
data={this.state.monTabPost}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) =>
<View>
<Text>Mon post</Text>
<BlockPhoto title={item.title} />
</View>
}
/>
</View>
)
}
you have to add some styling in main container view, flex occupy the entire lists of data.
I tried using paddingBottom, but it didnt work for me.
Try adding marginBottom: 150 on the Flatlist component's style.

How to use PanResponder inside horizontal FlatList

I want to drag out the selected item from the horizontal FlatList and drop it to another area of the screen. The problem is that my FlatList wrapper must have a fixed height and when trying to pull out selected element out FlatList component overflows it and my element gets hidden.
I have tried to change zIndex and set overflow to visible but it does not work properly because setting zIndex works with siblings only and pretty buggy just yet, overflow:visible did not affect layout at all.
Here is the screenshot:
Here is my code:
import React from 'react';
import {
SafeAreaView,
View,
FlatList,
Text,
StyleSheet,
Animated,
PanResponder
} from 'react-native';
import { v4 } from 'uuid';
export default class App extends React.PureComponent{
state = {
data: [
{ id: v4(), title: 'Lightcoral', hex: '#eb7474' },
{ id: v4(), title: 'Orchid', hex: '#eb74dc' },
{ id: v4(), title: 'Mediumpurple', hex: '#9a74eb' },
{ id: v4(), title: 'Mediumslateblue', hex: '#8274eb' },
{ id: v4(), title: 'Skyblue', hex: '#74b6eb' },
{ id: v4(), title: 'Paleturquoise', hex: '#93ece2' },
{ id: v4(), title: 'Palegreen', hex: '#93ecb6' },
{ id: v4(), title: 'Khaki', hex: '#d3ec93' }
]
}
_position = new Animated.ValueXY()
_panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (event, gesture) => {
this._position.setValue({ x: gesture.dx, y: gesture.dy})
},
onPanResponderRelease: () => {}
})
_keyExtractor = (item) => item.id;
_renderItem = ({item}) => {
return (
<Animated.View
style={this._position.getLayout()}
{...this._panResponder.panHandlers}
>
<View style={[styles.itemBox, {backgroundColor: `${item.hex}`}]}>
<Text>{item.title}</Text>
</View>
</Animated.View>
)
}
render() {
const { data } = this.state
return (
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
<View style={styles.targetArea}>
<Text>Drop HERE!!!</Text>
</View>
<View style={{ height: 80, borderColor: 'black', borderWidth: 2 }}>
<FlatList
data={data}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
horizontal={true}
/>
</View>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
safeArea: {
flex: 1
},
container: {
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#fff',
},
itemBox: {
width: 80,
height: 80,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#fff'
},
targetArea: {
height: 150,
width: 150,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#eee',
backgroundColor: '#F5FCFF',
marginTop: 40
}
});
I want to move the selected item of flatList around the screen and put it on top of any other element of the screen, if i simply could programmatically set zIndex of each element - I would be over the moon but unfortunately it seems not working as simple as that. Please help me I very desperate(((
set overflow to visible in FlatList style.

How to build a home screen using gridview in react native?

I need to build a home screen with grid view in react-native. And that grid view should contain four Image buttons. Each image button should redirect to different pages. I am using the react-native-super-grid package.
If you need only 4 image button than no need to make a complex grid . Use below code only and if you need a complex gird than use this YouTube video link for better understanding.
import React, { Component } from 'react';
import { AppRegistry, View,Image } from 'react-native';
export default class FlexDirectionBasics extends Component {
render() {
return (
// Try setting `flexDirection` to `column`.
<View style={{flex: 1, }}>
<View style={{flex: 1, flexDirection: 'row', }}>
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
style={{flex:1}} />
<Image source={{uri: 'https://cdn-images-1.medium.com/max/512/1*qUlxDdY3T-rDtJ4LhLGkEg.png'}}
style={{flex:1}} />
</View>
<View style={{flex: 1, flexDirection: 'row', }}>
<Image source={{uri: 'https://rawgit.com/gorangajic/react-icons/master/react-icons.svg'}}
style={{flex:1}} />
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
style={{flex:1}} />
</View>
</View>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);
Let me know if need more discussion
Here is the code according to user package.
RenderItem function is work such as loop.
when you put 4 objects in sections array RenderItem will make a loop for 4 time.
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Image style={styles.img} source={require('./assets/3.jpg')} />
<SuperGridSectionList
itemDimension={130}
sections={[
{
// all your style and data will be here according to your grid package
data: [
{ name: '1' }, { name: '2' },
{ name: '3' }, { name: '4' },
]
}
]}
style={styles.gridView}
renderItem={({ item }) => (
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={() => { alert("clicked me") }}>
<Image source={require("./assets/set2.png")} />
</TouchableOpacity>
</View>
You can install "npm install react-native-super-grid" and try this. You can change itemDimension then it will change number of icons should display on screen. This is only sample you can change what ever you needs.
import React, { Component } from "react";
import {
StyleSheet,
View,
Text,
TouchableOpacity,
PixelRatio,
Image
} from "react-native";
import { Container, Header, Content } from "native-base";
import GridView from "react-native-super-grid";
const buttons = [
{
name: "test1",
image: require("./src/icons/test1.png"),
key: 1
},
{
name: "test2",
image: require("./src/icons/test2.png"),
key: 2
},
{
name: "test3",
image: require("./src/icons/test3.png"),
key: 3
},
{
name: "test4",
image: require("./src/icons/test4.png"),
key: 4
},
];
class Home extends Component {
constructor(props) {
super(props);
}
onPress(){
}
render() {
return (
<Container style={styles.container}>
<Content contentContainerStyle={styles.contentContainerStyle}>
<GridView
itemDimension={180}
items={buttons}
renderItem={item => (
<View style={styles.gridCompenentContainer}>
<TouchableOpacity
onPress={this.onPress.bind(this)}
activeOpacity={0.8}
style={styles.touchView}
>
<Image
style={{ width: 60, height: 60 }}
source={item.image}
/>
</TouchableOpacity>
<View style={styles.textView}>
<Text style={styles.text}>{item.name} </Text>
</View>
</View>
)}
/>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#fff"
},
contentContainerStyle: {
backgroundColor: "#fff",
justifyContent: "center"
},
gridCompenentContainer: {
width: 160,
height: 140,
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
touchView: {
width: 80,
justifyContent: "center",
alignItems: "center",
height: 80,
borderRadius: 40,
backgroundColor: "#0099cc"
},
textView: {
width: 140,
height: 50,
justifyContent: "center",
alignItems: "center"
},
text: {
width: 140,
fontSize: 12,
textAlign: "center",
color: "#0099cc"
}
});
export default Home;
thara### please refer this to get know how to implement react navigation or official documentation React Navigation.
You can add route for button press event. like
onPress={() =>
this.props.navigation.navigate('screen2');
}
https://facebook.github.io/react-native/docs/navigation#react-navigation

React Native FlatList not scrolls vertically with custom renderItem and unable to view all items in the list

I have created a screen put a image as a background for whole screen. I want to show an array list with FlatList. I have created a separate function component as a cardItem for FlatList item and wrapped it inside a <View></View> element. I have searched a lot and read the question answers on lot of sites also, but my FlatList doesn't scrolls vertically and eventually i am unable to view some items in the ArrayList. Here is my some Sample Code :
<View
style={{
width: "100%",
height: "100%",
alignItems: "stretch",
flexDirection: "column",
position: "absolute",
justifyContent: "center"
}}
>
<View
style={{
flex: 2,
alignItems: "center",
justifyContent: "center",
alignSelf: "center"
}}
>
<Text
style={{ fontSize: 22, fontWeight: "bold", color: "#ffffff" }}
>
My Events List
</Text>
</View>
<View
style={{
flex: 8,
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 15
}}
>
<FlatList
style={{ width: "100%", marginBottom: 15 }}
data={eventsCreatedList}
keyExtractor={item => {
return item.id;
}}
renderItem={({ item }) => <EventsCreatedListItem item={item} />}
/>
</View>
</View>
Please tell me where i am going wrong. Thank in advance guys!
I tried this sample at https://snack.expo.io/?session_id=snack-session-wKlWVe6l2, which is working with the Flatlist and showing in a scroll view. Please have a look.
import React from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text } from 'react-native';
import Constants from 'expo-constants';
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'Fourth Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Fifth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Sixth Item',
},
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'Seventh Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Eighth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Nineth Item',
},
];
function Item({ title }) {
return (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
}
export default function App() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: Constants.statusBarHeight,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});