首页 > 解决方案 > React Native Scroll View 弹回顶部

问题描述

我正在尝试在我的项目中实现一个 SrollView,但是由于某种原因,当我尝试滚动浏览其中的所有元素时,它会弹回到 ScrollView 的顶部。我环顾四周,通过添加flex:1到 ScrollView 解决了其他一些问题,但是当我尝试让整个 ScrollView 离开屏幕时。我试图添加position:'absolute'到 ScrollView 但这只会导致 scrollView 不再移动

我也尝试过,<KeyboardAwareScrollView>但是屏幕似乎没有适应输入。

这是我的代码:

import React from "react";
import {
  View,
  Dimensions,
  Platform,
  ActivityIndicator,
  Alert,
  Image,
  KeyboardAvoidingView,
  TouchableHighlight,
  Keyboard
} from "react-native";
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import { Form, Item, Input, Label, Button, Text, Picker } from "native-base";
import * as firebase from "firebase";
import { ScrollView } from "react-native-gesture-handler";
import { LinearGradient, ImagePicker, Permissions } from "expo";
import Modal from "react-native-modal";
import uuid from "uuid";
import axios from "axios";


<View style={{borderBottomLeftRadius:20, borderBottomRightRadius:20, marginTop:20}}>
              <TouchableHighlight onPress={this.toggleModal} underlayColor="white">
              <Image source={{ uri: this.state.imageUrl }} style={{ width: SCREEN_WIDTH, height: SCREEN_HEIGHT/3, borderRadius: 20, marginBottom:20 }}/>
              </TouchableHighlight>
              </View>
              }
          {!this.state.loading ? (
                <Button
                  full
                  style={{
                    fontFamily: "nunito",
                    backgroundColor: 'transparent',
                    alignSelf: "center",
                    height: SCREEN_HEIGHT/3,
                    width: SCREEN_WIDTH
                  }}
                  onPress={() => this.alertOptions()}
                >
                <View style={{flexDirection:'column'}}>
                <Text
                    style={{
                      fontFamily: "nunito",
                       color: "black",
                       fontSize: 30,
                       textAlign: 'center'
                    }}
                  >
                    {this.state.imageUrl === ""
                      ? "Tap"
                      : ""}
                  </Text>
                  <Text
                    style={{
                      fontFamily: "nunito",
                       color: "black",
                       fontSize: 30,
                       textAlign: 'center'
                    }}
                  >
                    {this.state.imageUrl === ""
                      ? "to"
                      : ""}
                  </Text>
                  <Text
                    style={{
                      fontFamily: "nunito",
                       color: "black",
                       fontSize: 30,
                       textAlign:'center'
                    }}
                  >
                    {this.state.imageUrl === ""
                      ? "Upload Photo"
                      : ""}
                  </Text>
                  </View>
                </Button>
              ) : (
                <Text style={{color:'white', textAlign:'center', fontSize: 40, marginTop: 25}}>Loading...Please Wait</Text>
              )}
              </View>
              <View>
<ScrollView showsVerticalScrollIndicator={false} style={{ borderTopRightRadius: -20, borderTopLeftRadius: -20, backgroundColor:"#a2b6d8",}}>
            <Text
              style={{
                fontSize: 28,
                color: "#404040",
                fontWeight: "700",
                marginLeft: 12,
                marginBottom: 10,
                marginTop: 20,
                textAlign: "center"
              }}
            >
              Enter your details below
            </Text>
            <Form>
              <Item stackedLabel rounded>
                <Label style={{ fontFamily: "nunito" }}>
                  Address (Street, City)<Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ address: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>
              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Name
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ name: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Contractor{" "}
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ contractor: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Zip
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ zip: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Type of work performed
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ performed: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

            </Form>

            <View
              style={{
                flexDirection: "row",
                justifyContent: "center",
                alignItems: "center",
                marginTop: 20,
                marginBottom: 10
              }}
            >
            </View>

            <View
              style={{
                justifyContent:'space-around',
                marginLeft: 15,
                flexDirection:'row'
              }}
            >
              {!this.state.loader ? (
                <Button
                  full
                  style={{
                    fontFamily: "nunito",
                    backgroundColor: "#f3d95c",
                    width: SCREEN_WIDTH/3,
                    borderRadius:50,
                    shadowColor: "#918236",
                    shadowOffset: {
                      width: 0,
                      height: 0,
                    },
                    shadowOpacity: 0.8,
                    shadowRadius: 4,
                    // alignSelf: "center",
                  }}
                  onPress={() => this.add()}
                >
                  <Text
                    style={{
                      fontFamily: "nunito",
                      color: "black",
                      fontSize: 22
                    }}
                  >
                    SEND
                  </Text>
                </Button>
              ) : (
                <ActivityIndicator size="large" color="#f3d95c" />
              )}
              <Button
              onPress={() => this.logout()}
              style={{ alignSelf: "center", marginBottom: 20, backgroundColor:'red', borderRadius:50 }}
            >
              <Text style={{fontSize:18}}>Logout</Text>
            </Button>
            </View>
            </ScrollView>
 </View>

标签: react-nativescrollview

解决方案


替换文件的内容。

EnterDetails.js

import React from "react";
import {
  View,
  Dimensions,
  Platform,
  ActivityIndicator,
  Alert,
  Image,
  KeyboardAvoidingView,
  TouchableHighlight,
  TouchableWithoutFeedback,
  Keyboard,
  ScrollView
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { Form, Item, Input, Label, Button, Text, Picker } from "native-base";
import * as firebase from "firebase";
import { LinearGradient, ImagePicker, Permissions } from "expo";
import Modal from "react-native-modal";
import uuid from "uuid";
import axios from "axios";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;

export default class EnterDetails extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loader: false,
      loading: false,
      address: "",
      name: "",
      contractor: "",
      zip: "",
      email: "frank.gully2800@gmail.com",
      // userEmail: firebase.auth().currentUser.email,
      imageUrl: "",
      performed: ""
    };
  }

  state = {
    isModalVisible: false
  };

  toggleModal = () => {
    this.setState({ isModalVisible: !this.state.isModalVisible });
  };

  onValueChange(value) {
    this.setState({
      selected: value
    });
  }

  imagePicker = () => {
    Permissions.askAsync(Permissions.CAMERA_ROLL);
    ImagePicker.launchImageLibraryAsync({
      allowsEditing: false,
      base64: true
    }).then(async result => {
      const blob = await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function() {
          resolve(xhr.response);
        };
        xhr.onerror = function(e) {
          reject(new TypeError("Network request failed"));
        };
        xhr.responseType = "blob";
        xhr.open("GET", result.uri, true);
        xhr.send(null);
      });

      const ref = firebase
        .storage()
        .ref()
        .child(uuid.v4());
      const snapshot = await ref.put(blob);
      blob.close();
      let imageUrl = await snapshot.ref.getDownloadURL();

      this.setState({ imageUrl: imageUrl, loading: false });
    });
  };
  cameraUsage = () => {
    this.setState({ loading: true });
    Permissions.askAsync(Permissions.CAMERA);
    ImagePicker.launchCameraAsync({
      allowsEditing: false,
      base64: true
    }).then(async result => {
      const blob = await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function() {
          resolve(xhr.response);
        };
        xhr.onerror = function(e) {
          reject(new TypeError("Network request failed"));
        };
        xhr.responseType = "blob";
        xhr.open("GET", result.uri, true);
        xhr.send(null);
      });

      const ref = firebase
        .storage()
        .ref()
        .child(uuid.v4());
      const snapshot = await ref.put(blob);
      blob.close();
      let imageUrl = await snapshot.ref.getDownloadURL();

      this.setState({ imageUrl: imageUrl, loading: false });
    });
  };

  add = () => {
    if (
      this.state.zip !== "" &&
      this.state.address !== "" &&
      this.state.name !== "" &&
      this.state.contractor !== "" &&
      this.state.email !== "" &&
      this.state.imageUrl !== "" &&
      this.state.performed !== ""
    ) {
      const {
        name,
        imageUrl,
        contractor,
        address,
        email,
        zip,
        performed
      } = this.state;
      axios
        .post(
          "https://us-central1-cccproject-2b2f6.cloudfunctions.net/sendMailToUser",
          {
            zip: zip,
            name: name,
            imageUrl: imageUrl,
            address: address,
            email: email,
            contractor: contractor,
            performed: performed,
            userEmail: this.state.userEmail
          }
        )
        .then(response => {
          Alert.alert("Details Sent");
        })
        .catch(error => {});
    } else {
      Alert.alert("Please Complete The form");
    }
  };
  alertOptions = () => {
    Alert.alert(
      "Photo Options",
      "Choose how you upload your photo",
      [
        { text: "Camera", onPress: () => this.cameraUsage() },
        {
          text: "Image Library",
          onPress: () => this.imagePicker()
        },
        {
          text: "Cancel",
          onPress: () => console.log("Day sayd no :("),
          style: "cancel"
        }
      ],
      { cancelable: false }
    );
  };

  logout = () => {
    firebase
      .auth()
      .signOut()
      .then(s => {
        this.props.navigation.navigate("Login");
      })
      .catch(e => {});
  };

  render() {
    return (
      <View style={{ flex: 1 }}>
        <View
          style={{
            width: SCREEN_WIDTH,
            height: SCREEN_HEIGHT / 3,
            alignSelf: "center",
            marginTop: 0,
            backgroundColor: "red",
            borderBottomLeftRadius: 20,
            borderBottomRightRadius: 20
          }}
        >
          {this.state.imageUrl === "" ? null : (
            <View
              style={{
                borderBottomLeftRadius: 20,
                borderBottomRightRadius: 20,
                marginTop: 20
              }}
            >
              <TouchableHighlight
                onPress={this.toggleModal}
                underlayColor="white"
              >
                <Image
                  source={{ uri: this.state.imageUrl }}
                  style={{
                    width: SCREEN_WIDTH,
                    height: SCREEN_HEIGHT / 3,
                    borderRadius: 20,
                    marginBottom: 20
                  }}
                />
              </TouchableHighlight>
            </View>
          )}
          {!this.state.loading ? (
            <Button
              full
              style={{
                fontFamily: "nunito",
                backgroundColor: "transparent",
                alignSelf: "center",
                height: SCREEN_HEIGHT / 3,
                width: SCREEN_WIDTH
              }}
              onPress={() => this.alertOptions()}
            >
              <View style={{ flexDirection: "column" }}>
                <Text
                  style={{
                    fontFamily: "nunito",
                    color: "black",
                    fontSize: 30,
                    textAlign: "center"
                  }}
                >
                  {this.state.imageUrl === "" ? "Tap" : ""}
                </Text>
                <Text
                  style={{
                    fontFamily: "nunito",
                    color: "black",
                    fontSize: 30,
                    textAlign: "center"
                  }}
                >
                  {this.state.imageUrl === "" ? "to" : ""}
                </Text>
                <Text
                  style={{
                    fontFamily: "nunito",
                    color: "black",
                    fontSize: 30,
                    textAlign: "center"
                  }}
                >
                  {this.state.imageUrl === "" ? "Upload Photo" : ""}
                </Text>
              </View>
            </Button>
          ) : (
            <Text
              style={{
                color: "white",
                textAlign: "center",
                fontSize: 40,
                marginTop: 25
              }}
            >
              Loading...Please Wait
            </Text>
          )}
        </View>
        <View style={{ borderWidth: 2, borderColor: "pink", flex: 1 }}>
          <ScrollView
            style={{
              borderTopRightRadius: -20,
              borderTopLeftRadius: -20,
              backgroundColor: "#a2b6d8",
              position: "relative",
              flex: 1
            }}
          >
            <Text
              style={{
                fontSize: 28,
                color: "#404040",
                fontWeight: "700",
                marginLeft: 12,
                marginBottom: 10,
                marginTop: 20,
                textAlign: "center"
              }}
            >
              Enter your details below
            </Text>
            <Form>
              <Item stackedLabel rounded>
                <Label style={{ fontFamily: "nunito" }}>
                  Address (Street, City)
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ address: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>
              <Modal isVisible={this.state.isModalVisible}>
                <Image
                  source={{ uri: this.state.imageUrl }}
                  style={{
                    width: SCREEN_WIDTH / 1.1,
                    height: SCREEN_HEIGHT / 1.1,
                    justifyContent: "center",
                    alignSelf: "center",
                    marginBottom: 0
                  }}
                  resizeMode="contain"
                />
                <Button
                  style={{
                    backgroundColor: "red",
                    borderBottomRightRadius: 20,
                    borderBottomLeftRadius: 20,
                    borderTopLeftRadius: 20,
                    borderTopRightRadius: 20,
                    width: SCREEN_WIDTH - 20,
                    alignSelf: "center",
                    justifyContent: "center"
                  }}
                  onPress={this.toggleModal}
                >
                  <Text style={{ fontFamily: "nunito", textAlign: "center" }}>
                    Close
                  </Text>
                </Button>
              </Modal>
              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Name
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ name: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Contractor{" "}
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ contractor: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Zip
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ zip: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>

              <Item stackedLabel>
                <Label style={{ fontFamily: "nunito" }}>
                  Type of work performed
                  <Text style={{ color: "red", marginLeft: 10 }}>*</Text>
                </Label>
                <Input
                  placeholderTextColor="#9e9e9e"
                  placeholder="Required"
                  onChangeText={e => this.setState({ performed: e })}
                  style={{ fontFamily: "nunito" }}
                />
              </Item>
            </Form>

            <View
              style={{
                flexDirection: "row",
                justifyContent: "center",
                alignItems: "center",
                marginTop: 20,
                marginBottom: 10
              }}
            ></View>

            <View
              style={{
                justifyContent: "space-around",
                marginLeft: 15,
                flexDirection: "row"
              }}
            >
              {!this.state.loader ? (
                <Button
                  full
                  style={{
                    fontFamily: "nunito",
                    backgroundColor: "#f3d95c",
                    width: SCREEN_WIDTH / 3,
                    borderRadius: 50,
                    shadowColor: "#918236",
                    shadowOffset: {
                      width: 0,
                      height: 0
                    },
                    shadowOpacity: 0.8,
                    shadowRadius: 4
                    // alignSelf: "center",
                  }}
                  onPress={() => this.add()}
                >
                  <Text
                    style={{
                      fontFamily: "nunito",
                      color: "black",
                      fontSize: 22
                    }}
                  >
                    SEND
                  </Text>
                </Button>
              ) : (
                <ActivityIndicator size="large" color="#f3d95c" />
              )}
              <Button
                onPress={() => this.logout()}
                style={{
                  alignSelf: "center",
                  marginBottom: 20,
                  backgroundColor: "red",
                  borderRadius: 50
                }}
              >
                <Text style={{ fontSize: 18 }}>Logout</Text>
              </Button>
            </View>
          </ScrollView>
        </View>
      </View>
    );
  }
}

应用程序.js

import React from "react";
import { AppLoading } from "expo";
import * as Font from "expo-font";
import { Ionicons } from "@expo/vector-icons";
import Routes from "./Routes";

import { View, StatusBar } from "react-native";
import * as firebase from "firebase";

var firebaseConfig = {//ADD YOUR CREDS HERE};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);
export default class App extends React.Component {
  state = {
    isReady: true,
    isTrue: false
  };
  async componentWillMount() {
    await Font.loadAsync({
      ...Ionicons.font,
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      nunito: require("./assets/nunito/Nunito-Regular.ttf"),
      MonReg: require("./assets/Montserrat-Regular.ttf"),
      MonBold: require("./assets/Montserrat-Bold.ttf")
    });
    this.setState({ isReady: false });
  }

  render() {
    setTimeout(() => this.setState({ isTrue: true }), 6000);
    if (this.state.isReady) {
      return <AppLoading />;
    }
    return (
      <View style={{ flex: 1 }}>
        <StatusBar backgroundColor="rgba(255,255,255,1)" />
        <Routes />
      </View>
    );
  }
}

推荐阅读