【问题标题】:MultipleScreens(like a stack) on top of one another in react native多个屏幕(如堆栈)在本机反应中相互叠加
【发布时间】:2020-03-25 03:37:50
【问题描述】:

在 react native 中,我们是否可以实现一个 UI,其中多个屏幕相互堆叠,每个屏幕在单击按钮时堆叠在另一个之上。

假设有屏幕 A。单击按钮后,屏幕 B 作为堆栈放置在屏幕 A 上,屏幕 A 仍然部分可见,因为屏幕 B 不占据整个屏幕布局。同样,在点击屏幕 B 中的按钮时,屏幕 C 会添加到堆栈中,并且屏幕 B 和背景中的屏幕 A 仍然可见。所有这些都带有左侧的侧面动画(类似于导航抽屉)。使用一个通用按钮,上述所有屏幕都可以从堆栈中弹出,前一个屏幕再次以侧面动画出现在顶部,这次是在右侧。

我想了解以上内容是否可以在本机反应中实现?如果是,我该如何实现?我希望我能展示设计,但我不能这样做。

【问题讨论】:

    标签: react-native react-native-android react-native-ios react-native-navigation stack-navigator


    【解决方案1】:

    使用react-native-vertical-view-pager,您可以做到。

    安装:

    npm install --save react-native-vertical-view-pager
    

    或者用纱线(如果你使用纱线):

    yarn add react-native-vertical-view-pager
    

    并按如下方式使用:

    import React from 'react';
    import { StyleSheet, Text, View, Dimensions } from 'react-native';
    import VerticalViewPager from 'react-native-vertical-view-pager';
    
    const { width, height } = Dimensions.get('window');
    
    export default class App extends React.Component {
        render() {
            return (
                <VerticalViewPager
                    showsVerticalScrollIndicator={false}>
                    <View style={[styles.page_container, {backgroundColor: 'pink'}]}>
                        <Text>Page1: Open up App.js to start working on your app!</Text>
                    </View>
                    <View style={[styles.page_container, {backgroundColor: 'olive'}]}>
                        <Text>Page2: Changes you make will automatically reload.</Text>
                    </View>
                    <View style={[styles.page_container, {backgroundColor: 'lightblue'}]}>
                        <Text>Page3: Shake your phone to open the developer menu.</Text>
                    </View>
                </VerticalViewPager>
            );
        }
    }
    
    const styles = StyleSheet.create({
        page_container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            width,
            height
        }
    });
    

    将您的屏幕放在视图的位置。

    【讨论】:

      【解决方案2】:

      我可以使用名为“react-native-modalfy”的非常酷的库来实现此功能。

      import React, { PureComponent } from 'react'
      import {
        Easing,
        Dimensions,
        StatusBar,
        StyleSheet,
        Text,
        View,
      } from 'react-native'
      import { ModalProvider, createModalStack } from 'react-native-modalfy'
      
      import CardModal from './modals/CardModal'
      import Button from './components/Button'
      
      const { width } = Dimensions.get('screen')
      
      const config = { ModalA: CardModal, ModalB: CardModal, ModalC: CardModal }
      
      const defaultOptions = {
        transitionOptions: animatedValue => ({
          opacity: animatedValue.interpolate({
            inputRange: [0, 1, 2],
            outputRange: [0, 1, .9],
          }),
          transform: [
            {
              perspective: 2000
            },
            {
              translateX: animatedValue.interpolate({
                inputRange: [0, 1, 2],
                outputRange: [-width / 2, 0, 25],
              }),
            },
            {
              scale: animatedValue.interpolate({
                inputRange: [0, 1, 2],
                outputRange: [1.2, 1, .9],
              }),
            },
          ],
        }),
        animateInConfig: {
          easing: Easing.bezier(.42,-0.03,.27,.95),
          duration: 450,
        },
        animateOutConfig: {
          easing: Easing.bezier(.42,-0.03,.27,.95),
          duration: 450,
        },
      }
      
      const stack = createModalStack(config, defaultOptions)
      
      class App extends PureComponent {
        render() {
          return (
            <ModalProvider stack={stack}>
              <View style={styles.container}>
                <StatusBar animated hidden translucent />
                <Text style={styles.title}>RNM</Text>
                <Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
                <Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
                <Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
              </View>
            </ModalProvider>
          )
        }
      }
      
      const styles = StyleSheet.create({
        container: {
          flex: 1,
          backgroundColor: 'indigo',
          alignItems: 'center',
          justifyContent: 'center'
        },
        title: {
          color: 'white',
          fontSize: 54,
          fontWeight: 'bold',
          marginBottom: 50,
        },
      })
      
      export default App

      import React, { PureComponent } from 'react'
      import {
        Button as ButtonModule,
        Dimensions,
        StyleSheet,
        Text,
        View,
      } from 'react-native'
      
      import Button from '../components/Button'
      
      const { width: ww, height: wh } = Dimensions.get('screen')
      
      class CardModal extends PureComponent {
        componentDidMount() {
          const { modal } = this.props
          this.modalListenerID = modal.addListener('onAnimate', this._handleAnimation)
        }
      
        componentWillUnmount() {
          this.modalListenerID?.remove()
        }
      
        _handleAnimation = animatedValue => {
          const { currentModal } = this.props.modal
          console.info(`${currentModal}:`, animatedValue)
        }
      
        render() {
          const {
            currentModal,
            closeModal,
            closeModals,
            closeAllModals,
            params: { color },
          } = this.props.modal
      
          return (
            <View style={[styles.card]}>
              <Text style={styles.title(color)}>{currentModal}</Text>
              <Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
              <Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
              <Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
              
              <ButtonModule title="Close" onPress={closeModal} color="dodgerblue" />
              <ButtonModule title={`Close all ${currentModal}`} onPress={() => closeModals(currentModal)} color="dodgerblue" />
              <ButtonModule title="Close all modals" onPress={closeAllModals} color="red" />
            </View>
          )
        }
      }
      
      const styles = StyleSheet.create({
        title: color => ({
          color,
          fontSize: 48,
          fontWeight: 'bold',
          marginBottom: 50,
        }),
        card: {
          marginRight : 90,
          width: ww,
          height: wh,
          backgroundColor: 'cyan',
          elevation: 0,
          alignItems: 'center',
          justifyContent: 'center',
          borderRadius: 0,
        },
      })
      
      export default CardModal

      import React, { PureComponent } from 'react'
      import { TouchableOpacity, StyleSheet, Text } from 'react-native'
      import { withModal } from 'react-native-modalfy'
      
      class Button extends PureComponent {
        openModal = () => {
          const { color, modalToOpen, modal } = this.props
      
          modal.openModal(modalToOpen, { color })
        }
      
        render() {
          const { color, label } = this.props
      
          return (
            <TouchableOpacity onPress={this.openModal} style={styles.button(color)}>
              <Text style={styles.label}>{label}</Text>
            </TouchableOpacity>
          )
        }
      }
      
      const styles = StyleSheet.create({
        button: backgroundColor => ({
          backgroundColor,
          paddingHorizontal: 60,
          paddingVertical: 21,
          borderRadius: 21,
          marginBottom: 30,
        }),
        label: {
          fontSize: 16,
          fontWeight: '800',
          color: 'white',
          textAlign: 'center',
        },
      })
      
      export default withModal(Button)

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-27
        相关资源
        最近更新 更多