How to make two Scrollview on the same screen in React Native

Asked

Viewed 120 times

1

I have a screen with several frames fixed height, and within each frame I have an amount of items. I need a ScrollView on the whole screen to scroll the frames, but also need another ScrollView inside each frame to scroll the items in that frame.

The problem is that when I put one ScrollView involving the entire screen, the second Scrollview` from inside the frames stops working, so I can’t scroll the items from that frame.

I tried to use the scrollEnabled={false} to enable or disable the ScrollView of the whole screen, but even so the ScrollView from within the frame where roll the items does not work. The ScrollView of the board only works if I disguise the ScrollView that wraps the entire screen by a View with flex: 1, but that way I won’t be able to scroll the screen to view all the frames.

This is an example image, I need to scroll the screen to visualize from "frame 1" to "frame 3", and I also need to scroll inside each frame to visualize from "item 1" to "item 7". How can I solve this problem or get the same functionality otherwise?

inserir a descrição da imagem aqui

That’s the code I have at the moment:

import * as React from 'react';
import { Text, View, StyleSheet, ScrollView } from 'react-native';

export default function App() {
  return (
    <ScrollView style={styles.container} scrollEnabled={false}>
      <View style={styles.quadro}>
        <ScrollView>
          <Text style={styles.titulo}>QUADRO 1</Text>
          <View style={styles.item}>
            <Text>Item 1</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 2</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 3</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 4</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 5</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 6</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 7</Text>
          </View>
        </ScrollView>
      </View>

      <View style={styles.quadro}>
        <ScrollView>
          <Text style={styles.titulo}>QUADRO 2</Text>
          <View style={styles.item}>
            <Text>Item 1</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 2</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 3</Text>
          </View>
          <View style={styles.item}>
            <Text>Item</Text>
          </View>
          <View style={styles.item}>
            <Text>Item</Text>
          </View>
          <View style={styles.item}>
            <Text>Item</Text>
          </View>
        </ScrollView>
      </View>

      <View style={styles.quadro}>
        <ScrollView>
          <Text style={styles.titulo}>QUADRO 3</Text>
          <View style={styles.item}>
            <Text>Item 1</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 2</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 3</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 4</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 5</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 6</Text>
          </View>
          <View style={styles.item}>
            <Text>Item 7</Text>
          </View>
        </ScrollView>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    backgroundColor: '#ecf0f1',
    padding: 20,
  },
  titulo: {
    textAlign: 'center',
    fontWeight: 'bold',
  },
  quadro: {
    backgroundColor: 'yellow',
    height: 300,
    marginTop: 30,
    width: 200,
    borderWidth: 3,
  },
  item: {
    height: 50,
    backgroundColor: 'red',
    margin: 5,
    borderWidth: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

1 answer

1


First, I’m going to assign the style of container for a View that will contain all the code, to avoid throwing error (at least in my tests) and we will activate the scrollEnabled.

How does it look:

return (
 <View style={styles.container}>
   <ScrollView scrollEnabled>
    // ...
   </ScrollView>
 </View>
)

Now comes the following detail, what you’re trying to do is what we call Nested Scrollview (ScrollView Nested) and in this case we should observe the following, by default, the nesting of ScrollViews is automatically activated on iOS, but to have it in Android, we have to define the props nestedScrollEnabled as true.

How does it look:


import * as React from 'react';
import { Text, View, StyleSheet, ScrollView } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <ScrollView scrollEnabled>
        <View style={styles.quadro}>
          <ScrollView nestedScrollEnabled>
            <Text style={styles.titulo}>QUADRO 1</Text>
            <View style={styles.item}>
              <Text>Item 1</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 2</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 3</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 4</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 5</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 6</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 7</Text>
            </View>
          </ScrollView>
        </View>

        <View style={styles.quadro}>
          <ScrollView nestedScrollEnabled>
            <Text style={styles.titulo}>QUADRO 2</Text>
            <View style={styles.item}>
              <Text>Item 1</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 2</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 3</Text>
            </View>
            <View style={styles.item}>
              <Text>Item</Text>
            </View>
            <View style={styles.item}>
              <Text>Item</Text>
            </View>
            <View style={styles.item}>
              <Text>Item</Text>
            </View>
          </ScrollView>
        </View>

        <View style={styles.quadro}>
          <ScrollView nestedScrollEnabled>
            <Text style={styles.titulo}>QUADRO 3</Text>
            <View style={styles.item}>
              <Text>Item 1</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 2</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 3</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 4</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 5</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 6</Text>
            </View>
            <View style={styles.item}>
              <Text>Item 7</Text>
            </View>
          </ScrollView>
        </View>
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    backgroundColor: '#ecf0f1',
    padding: 20
  },
  titulo: {
    textAlign: 'center',
    fontWeight: 'bold'
  },
  quadro: {
    backgroundColor: 'yellow',
    height: 300,
    marginTop: 30,
    width: 200,
    borderWidth: 3
  },
  item: {
    height: 50,
    backgroundColor: 'red',
    margin: 5,
    borderWidth: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

See how it looks on snack.expoio..

If you own the EXPO, scan the Qrcode with the app

inserir a descrição da imagem aqui

  • It worked. That’s exactly what I needed. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.