Florian Wittmann
Florian Wittmann

Reputation: 73

Scroll horizontal and vertical with ScrollViews in React Native

I try to implement a horizontal AND vertical Scrolling like the following:

ScrollPreviewMock.

The horizontal scrolling shows featured content as images (should be clickable). The vertical scrolling has other clickable items.

My first attempt was to use two ScrollViews both with position absolute, but the horizontal ScrollView consumes all touch events (even after adding pointerEvents={"box-none"}).

That is what I tried in that case:

import React, { Component } from "react";
import { Dimensions, ScrollView, Text, StyleSheet, View } from "react-native";
const DimensionsWindowWidth = Dimensions.get("window").width;

export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                <ScrollView horizontal={true} style={styles.scrollView}>
                    <View style={styles.slide}>
                        <Text>H1</Text>
                    </View>
                    <View style={styles.slide}>
                        <Text>H2</Text>
                    </View>
                    <View style={styles.slide}>
                        <Text>H3</Text>
                    </View>
                </ScrollView>
                <ScrollView pointerEvents={"box-none"} style={styles.scrollView}>
                    <View style={styles.item}>
                        <Text>V1</Text>
                    </View>
                    <View style={styles.item}>
                        <Text>V2</Text>
                    </View>
                    <View style={styles.item}>
                        <Text>V3</Text>
                    </View>
                    <View style={styles.item}>
                        <Text>V4</Text>
                    </View>
                </ScrollView>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    slide: {
        padding: 100,
        width: DimensionsWindowWidth,
        height: "100%"
    },
    scrollView: {
        position: "absolute",
        width: "100%",
        height: "100%"
    },
    item: {
        margin: 40,
        height: 100
    }
});

(Also as snack: https://snack.expo.io/Hyb7x-qQQ)

My second try was to use a PanResponder and in onPanResponderMove methods to use the ScrollViews scrollTo method. But then it seems I have to implement all the ScrollView special like smooth scrolling and bounce back on my own.

Any ideas how I could solve this while having both, the background in horizontal and the items in vertical scrolling clickable?

Upvotes: 7

Views: 32997

Answers (4)

Austin Poulson
Austin Poulson

Reputation: 901

Here's a simplified set of code based on the other answers here. All you need is nested scrollviews, with the inner one set to horizontal.

<ScrollView>
<ScrollView horizontal={true}>
  //content
</ScrollView>
</ScrollView>

Upvotes: 0

Rajesh Bhartia
Rajesh Bhartia

Reputation: 758

Here I can scroll both vertically and horizontally. I tested it for android.

import React, { Component } from "react";
import { List, ListItem, Text } from "native-base";
import { View, ScrollView } from "react-native";

class Table extends Component {
    render() {
        return (
            <View>
                <ScrollView>
                <ScrollView horizontal={true}>
                    <List>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                        <Text>COMEDY </Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    <ListItem>
                        <Text>COMEDY :</Text>
                        <Text>Hangover </Text>
                    </ListItem>
                    </List>
                </ScrollView>
                </ScrollView>
            </View>
        );
    }
}

export default Table;

Upvotes: 5

Ali Zeynalov
Ali Zeynalov

Reputation: 3017

here is how I implement vertical and horizontal scrolling in my app for my Grid Table. It works fine for my on both IOS and ANDROID. I hope it will be helpful for you.

 import {Dimensions, AsyncStorage,View,Image, TextInput,ScrollView,FlatList, Platform} from 'react-native';

const {width, height} = Dimensions.get("window"),
    vw = width / 100
vh = height / 100


styles={
    parentScrollViewStyle: {
        height: height-300,
        borderWidth: 1,
        borderColor: '#D3D3D3'
    },
    childScrollViewStyle: {
        borderWidth: 1,
        borderColor: '#D3D3D3'
    },
    gridStyle: {
        width: '100%',
        marginTop: 20
    }
}




<Grid style={styles.gridStyle} >

    <ScrollView style={styles.parentScrollViewStyle}>
        <ScrollView horizontal={true}  contentContainerStyle={styles.childScrollViewStyle}>

         //here your child views to render.

        </ScrollView>
    </ScrollView>
</Grid>

Upvotes: 3

Sait Banazili
Sait Banazili

Reputation: 1363

In IOS you can simply use nested ScrollView's for such behaviour but in Android you will need something else.

Take a look at react-native-nested-scroll-view which claims to do that only for Android. I haven't used it but seems like it uses the native NestedScrollView class.

Upvotes: 4

Related Questions