无法在 scrollView 中滚动

IT技术 javascript css reactjs react-native uiscrollview
2021-02-22 10:03:40

我有一个屏幕,我在其中输入输入字段并相应地获得搜索结果。该列表在 ScrollView 中呈现,但在键盘打开时(在 Android 中)它仍然不允许我滚动。

我怎样才能解决这个问题?

  return (
    <>
      {addressesFound.length > 0 ? (
        <ScrollView
          style={styles.searchResultsContainer}
          keyboardShouldPersistTaps={'always'}
          keyboardDismissMode={'on-drag'}>
          {addressesFound.map((addressDetails: addressDetailsType) => {
            return (
              <View
                key={addressDetails.placeName}
                style={styles.resultContainer}>
                <Text
                  style={styles.text}>
                  {addressDetails.placeName}
                </Text>
              </View>
            );
          })}
        </ScrollView>
      ) : null}
    </>
  );
};
const styles = StyleSheet.create({
  searchResultsContainer: {
    width: moderateScale(400),
    paddingHorizontal: moderateScale(50),
    paddingRight: moderateScale(65),
    marginTop: moderateScale(10),
   flex:1,
  },
  resultContainer: {
    marginTop: moderateScale(10),
    borderBottomWidth: 1,
    borderBottomColor: 'grey',
  },
  text: {
    fontSize: moderateScale(15),
  },
});

在此处输入图片说明

我已经尝试过添加nestedScrollEnabled={true} ,但没有任何区别。

这就是上面提到的组件被调用的地方:

        <View style={styles.dropdown}>
          <LocationsFound
            addressesFound={locations.addressesFoundList} />
....
  dropdown: {
    position: 'absolute',
    top: moderateScale(215),
    zIndex: moderateScale(10),
    backgroundColor: '#fff',
    flex: 1,
  },

我尝试将 height: 80% 添加到dropdown. 这使得可以稍微滚动一下。但是,当键盘打开时,我可以滚动但不能滚动到最后。如果我添加高度:100%,我根本无法滚动。

6个回答

我为你的问题做了一个世博小吃并检查了它。我想我解决了。看一看:

这是世博小吃的链接

描述一下:

正如我发现的那样,您的问题是ScrollView在任何情况下都不会改变高度,即使给予更多height或给予paddingBottom.

所以我把它包裹ScrollView在一个View标签中,并给它这个样式:

scrollViewWrapper: {
     width: '100%',
     minHeight: '100%',
     paddingBottom: 1.3*keyboardHeight
 }

在此样式中,您会看到 parameter keyboardHeight,这是state我在componentDidMount以下代码中设置的

import {Keyboard} from 'react-native';
 
state = {
  keyboardHeight: 0,
}

componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
  'keyboardDidShow',
  this._keyboardDidShow
);
this.keyboardDidHideListener = Keyboard.addListener(
  'keyboardDidHide',
  this._keyboardDidHide
 );
}
_keyboardDidShow = (e) => {
  this.setState({
    keyboardHeight: e.endCoordinates.height,
  });
};

不得不提的是,你不能将paddingBottom: 1.3*keyboardHeight类组件外部的样式移动到styles对象中,因为它keyboardHeight是 a state,它可以在组件内部知道。

我建议你看看我在 expo小吃中的代码,以更好地理解我的描述。

我希望这能解决你的问题。

编辑功能组件

使用以下代码在编写功能组件时检测键盘高度:

const [keyboardHeight, setKeyboardHeight] = useState(0)
const [scrollViewVisibility, setScrollViewVisibility] = useState(false)
useEffect(() => {
  Keyboard.addListener("keyboardDidShow", _keyboardDidShow);

  // cleanup function
  return () => {
    Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
  };
}, []);
const _keyboardDidShow = (e) => {
  console.log("============in keyboardDidShow")
  setKeyboardHeight(e.endCoordinates.height)
};

我也编辑了世博小吃您可以查看它以查看工作示例。

如果我添加一个额外的height:'80%'到 mydropdown View这是整个 LocationsFound 列表组件的父级,这有点工作是否也可以在 LocationsFound 中移动高度样式?这样它就可以在不同的屏幕上自动计算。
2021-04-25 10:03:40
@Jnl 我修改了世博小吃并为此解决方案编写了一个编辑。看看这个。关于我的代码和你的代码之间的差异,是的,有一些差异,但我认为你已经在网络模式下检查了我的零食,在 iPhone 模式下检查了它。你会发现它和你的非常相似。
2021-04-27 10:03:40
我的 LocationFound 就像你的博览会,减去最顶部的容器 View & TextInput。如果我不单独将高度添加到下拉列表中,它就不会滚动。
2021-05-01 10:03:40
能不能根据功能组件修改一下?对于状态,我们可以使用 useState,对于 componentDidMount,我们可以使用 useEffect,但我无法弄清楚如何this.keyboardDidShowListener 在我的情况下替换
2021-05-06 10:03:40
此外,我无法真正评估您的小吃展,因为它与我的有点不同。就我而言,一旦显示列表,键盘仍处于打开状态。但是,在您的博览会中,当我搜索列表时键盘消失了。
2021-05-16 10:03:40

我认为如果你的 ScrollView 内容比屏幕小,它就不会滚动。所以你可以尝试制作 height: "150%" 或类似的东西,或者添加一个带有高度的空视图来拉伸你的 ScrollView 高于你的屏幕。

将 ScrollView 包装在具有高度 > 屏幕的视图中也将起作用。

如果我用另一个 View 包装 ScrollView <View style={{height: "auto", maxHeight: screenHeight*2}}>,则呈现的列表只是一个缺少内容的普通视图。我也尝试添加height: "150%"到,searchResultsContainer但它没有什么区别
2021-05-02 10:03:40

我认为您可以通过以下提示来解决此问题:1)调整 ScrollView 标签位置很可能它会直接在 <></> 内高于您的条件或添加视图标签,在 ScrollView 标签上方,例如

<><View style={{ Height: "auto", maxHeight: screenHeight}}><ScrollView>....</ScrollView></view></>

2)通过调整height、maxHeight属性和flex属性

如果它对你有用,请告诉我

条件是必要的。如果我用另一个 View 包装 ScrollView <View style={{height: "auto", maxHeight: screenHeight}}>,则呈现的列表只是一个缺少内容的普通视图。
2021-05-01 10:03:40
我究竟可以尝试“调整高度/最大高度”什么以及在哪里?将其添加到dropdown不起作用。
2021-05-11 10:03:40

我能想到三种解决方案(你可以尝试任何一种):

1-尝试将滚动视图包装在带有 flex=1 的视图标记中,如下所示:

<View style={{ flex:1 }}>
<ScrollView>
</ScrollView>
</View>

2-如果您不想使用视图,可以将 ScrollView flex 设置为 1

3-in 第一个解决方案,您可以使用空标签代替 View,如下所示:

<> 
</>
您是否尝试使用 flatlist 而不是 scorllview ?
2021-04-23 10:03:40
不,至少现在还没有。我在 qs 中添加了更多信息
2021-04-30 10:03:40
不幸的是,他们都没有对我有用。另外,我的退货中已经有一个空标签了。
2021-05-02 10:03:40

如果您的问题只是键盘打开,那么您可能需要查看KeyboardAvoidingView

我在这方面遇到了很多问题!您想尝试 prop 的所有设置behavior可能有一种适合您!

从他们的例子:

import React from 'react';
import { View, KeyboardAvoidingView, TextInput, StyleSheet, Text, Platform, 
TouchableWithoutFeedback, Button, Keyboard  } from 'react-native';

const KeyboardAvoidingComponent = () => {
   return (
     <KeyboardAvoidingView
       behavior={Platform.OS == "ios" ? "padding" : "height"}
       style={styles.container}
     >
       <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
         <View style={styles.inner}>
           <Text style={styles.header}>Header</Text>
           <TextInput placeholder="Username" style={styles.textInput} />
           <View style={styles.btnContainer}>
             <Button title="Submit" onPress={() => null} />
           </View>
         </View>
       </TouchableWithoutFeedback>
     </KeyboardAvoidingView>
   );
 };

 const styles = StyleSheet.create({
   container: {
     flex: 1
   },
   inner: {
     padding: 24,
     flex: 1,
     justifyContent: "space-around"
   },
   header: {
     fontSize: 36,
     marginBottom: 48
   },
   textInput: {
     height: 40,
     borderColor: "#000000",
     borderBottomWidth: 1,
     marginBottom: 36
   },
   btnContainer: {
     backgroundColor: "white",
     marginTop: 12
   }
 });

 export default KeyboardAvoidingComponent;