使用条件渲染时,有没有办法在 react-native 中保持 ScrollView 的位置?

Is there a way to mantain the position of ScrollView in react-native when using conditional rendering?

我使用带有一组拍照按钮的 react-native-camera,因为我想在一个屏幕中用更多内容填充我的应用程序,然后我使用 ScrollView 组件。每当我按下按钮拍照时,我都会渲染相机组件,但当返回到我的主视图时,ScrollView 会重置其位置。为此,我使用条件渲染。我用内容渲染相机或主视图。有没有简单或正确的方法来实现这一点?

所以,我知道有一种方法可以使用包含动画的滚动视图滚动到定义的位置,但这可能适用于我为相机设置的每个按钮的侦听器。我仍然不知道最好的选择是什么。

import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Button, ScrollView } from 'react-native';
import { RNCamera } from 'react-native-camera';

export default class BadInstagramCloneApp extends Component {
  constructor(props){
    super(props);
    this.state = {
      pictureType: null,
      isVisible: false,
      value1: null,
      value2: null
    }
  }

  render() {
    return (
        <View style={styles.subcontainer}>
          {this.state.isVisible === true
              ?
                <View style={styles.container}>
                  <RNCamera
                      ref={ref => {
                        this.camera = ref;
                      }}
                      style={styles.preview}
                      type={RNCamera.Constants.Type.back}
                      flashMode={RNCamera.Constants.FlashMode.on}
                      permissionDialogTitle={'Permission to use camera'}
                      permissionDialogMessage={'We need your permission to use your camera phone'}
                      onGoogleVisionBarcodesDetected={({ barcodes }) => {
                        console.log(barcodes);
                      }}
                  />
                  <View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
                    <TouchableOpacity onPress={this.takePicture.bind(this)} style={styles.capture}>
                      <Text style={{ fontSize: 14 }}> SNAP </Text>
                    </TouchableOpacity>
                  </View>
                </View>
              :
                <ScrollView>
                  <Button title='PHOTO 1' onPress={() => this.initTakingPicture("A")}/>
                  <Text>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam enim ex,
                    vehicula quis rhoncus et, tristique vitae est. Nullam nec odio est.
                    Nunc diam dolor, sagittis sed scelerisque nec, fringilla at tortor.
                    Donec vitae nibh risus. Integer et cursus ante.
                    Aliquam sodales elementum nisl, a bibendum ipsum sollicitudin eget.
                    Praesent non molestie augue. Curabitur at dui nunc.
                    Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci
                    luctus et ultrices posuere cubilia Curae; Donec sodales lacus et ex
                    posuere elementum. Pellentesque egestas eros ut elit viverra, maximus volutpat diam
                    rhoncus. Proin sed lacinia quam. Nunc a leo ullamcorper, accumsan lectus vitae,
                    tristique mauris. Duis non eros quis nisi efficitur laoreet non sit amet neque.
                    Aenean egestas, urna eget ultricies pretium, ligula ex euismod libero, ac dignissim sem velit vitae ex. Proin consequat quam sed tellus ornare, feugiat porta sapien lacinia. Integer scelerisque auctor lorem mattis lobortis. Sed consequat at nibh vel consequat. Ut ullamcorper aliquet commodo. Nam elementum sed elit ut aliquet. Proin urna est, ullamcorper in elit ut, tristique eleifend nisl.

                    Nulla facilisi. Duis in mollis urna. Cras lacus lectus, vulputate ut eleifend at, egestas eu arcu. Cras ornare nibh a euismod vestibulum. Vivamus facilisis sem non est dictum, ac porta massa venenatis. Duis non dolor fringilla, fringilla dui quis, feugiat arcu. Nullam in turpis id augue consectetur volutpat et eget arcu. Praesent tincidunt sit amet ligula ac bibendum.

                    Ut mollis vitae ex sed pellentesque. In et viverra leo, eu pulvinar velit. Nunc a maximus sem. Nunc venenatis turpis eu accumsan rutrum. Proin lacinia velit et ex venenatis, sed convallis nisi sodales. Aenean placerat dapibus ultrices. Aenean et interdum mauris. Etiam quis ante tincidunt, dapibus orci in, finibus velit. Cras lorem nibh, commodo at posuere ac, porta sodales massa. Nulla mollis cursus eros, a rhoncus magna posuere at. Fusce orci augue, sodales eget ligula at, lacinia vulputate lectus.

                    Cras rhoncus augue sed eleifend sagittis. Proin fermentum ut ligula eu faucibus. Sed ullamcorper urna lacus, eget venenatis felis aliquet at. Ut orci turpis, porttitor tempus sem quis, fringilla porta ante. Mauris bibendum enim purus, et congue ipsum cursus quis. Nunc quis aliquam erat. Phasellus id turpis at dui iaculis laoreet. Quisque sed tincidunt lacus. Ut efficitur, sapien id lacinia congue, lorem tortor dictum magna, ac eleifend lectus ligula non diam. Nulla enim orci, faucibus et sagittis a, mattis nec felis. Nunc ex mauris, ornare eget tellus vitae, sollicitudin fermentum sapien. Donec mollis nec nunc laoreet ultricies. Suspendisse imperdiet quam non molestie pellentesque. Maecenas facilisis urna eget tortor viverra cursus. Pellentesque lacinia lacinia turpis, eget lobortis sapien.
                  </Text>
                  <Button title='PHOTO 2' onPress={() => this.initTakingPicture("B")}/>
                  <Button title='SHOW RESULTS' onPress={this.showResults}/>
                </ScrollView>
          }
        </View>
    );
  }

  showResults = () => {
    console.log('VALOR1: ' + this.state.value1);
    console.log('VALOR2: ' + this.state.value2);
  }

  takePicture = async function() {
    if (this.camera) {
      const options = { quality: 0.5, base64: true };
      const data = await this.camera.takePictureAsync(options);
      console.log(data.uri);
      let fieldToSave = "value1" // Fallback
      if (this.state.pictureType === "A") {
        // Operation you need to do for pictureType A
        fieldToSave = "value1"
        //FIELTOSAVE DEBE OPTIMIZARSE Y GUARDAR SU VALOR EN LOCAL STATE
        //NO HACE FALTA CAMBIAR PARAMETROSS A ENVIAR PORQUE TOMAN EL MISMO NOMBRE
      } else if (this.state.pictureType === "B") {
        // Operation you need to do for pictureType B
        fieldToSave = "value2"
      }

      this.setState({
        isVisible: false,
        pictureType: null,
        [fieldToSave]: data.uri
      });
    }
  };

  initTakingPicture = (pictureType) => {
    this.setState({
      isVisible: true,
      pictureType: pictureType
    })
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: 'black'
  },
  subcontainer: {
    flex: 1,
    flexDirection: 'column',
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    padding: 15,
    paddingHorizontal: 20,
    alignSelf: 'center',
    margin: 20,
  },
});

为了以防万一,我使用了一些 Lorem Ipsum 来填充所有内容并使 ScrollView 滚动以查看问题本身。

我希望 ScrollView 本身保持其位置,而不是在重新渲染后重置

好的,正如用户@Javan_Poirier所说,有办法做到这一点。首先,我使用了一个附加到 scrollview 组件的监听器,它能够获取当前位置 'OnScroll'。然后,将此值保存在状态值上。最后,每次按下显示相机的按钮并将当前位置更新为状态值时,我都会调用一个方法,因此下次内容再次呈现时,我将使用状态设置自身的滚动视图位置。