You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中启用ScrollView双向滚动(无需ListView)及布局修复

解决React Native ScrollView双向滚动且子View垂直排列的问题

我明白你的问题了——你想让整个页面内容同时支持水平和垂直双向滚动,同时每个包含文本与输入框的区块能独立垂直排列,而不是现在这样挤在一行里。问题的核心是你直接将所有子View放在了设置horizontal={true}的ScrollView中,这会强制所有子元素横向排列,不符合你的需求。

修复思路

要实现双向滚动,我们需要嵌套两个ScrollView:

  1. 外层使用默认的垂直ScrollView,处理内容的垂直滚动(当内容高度超过屏幕时)
  2. 内层设置horizontal={true}的ScrollView,处理内容的水平滚动(当内容宽度超过屏幕时)
  3. 在水平ScrollView内部添加一个垂直容器(flexDirection: 'column'),让所有SwitchOuterSectionStyle区块垂直排列

修改后的完整代码

render() { 
  const { navigate } = this.props.navigation; 
  if (this.state.isLoading) { 
    return ( 
      <View style={{ flex: 1, paddingTop: 20 }}> 
        <ActivityIndicator /> 
      </View> 
    ); 
  } 
  return ( 
    <View style={styles.MainContainerViewCamp}> 
      <Text style={{ padding: 5, fontSize: 35, backgroundColor: '#00BCD4', marginBottom: 7 }}>Data Slabs</Text>
      {/* 外层垂直ScrollView:处理垂直滚动 */}
      <ScrollView 
        keyboardShouldPersistTaps='always' 
        directionalLockEnabled={false}
        style={{ flex: 1 }}
      >
        {/* 内层水平ScrollView:处理水平滚动 */}
        <ScrollView 
          horizontal={true}
          style={styles.container}
        >
          {/* 垂直容器:让所有区块垂直排列 */}
          <View style={{ flexDirection: 'column' }}>
            <View style={styles.SwitchOuterSectionStyle}> 
              <Text style={styles.textViewContainer}>A(1,1) </Text> 
              <TextInput placeholder="CPR*" value={this.state.cpr1} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpr1 => this.setState({ cpr1 })} underlineColorAndroid='transparent' /> 
              <TextInput placeholder="CPM*" value={this.state.cpm1} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpm1 => this.setState({ cpm1 })} underlineColorAndroid='transparent' /> 
            </View> 
            <View style={styles.SwitchOuterSectionStyle}> 
              <Text style={styles.textViewContainer}>B(0.75,0.75) </Text> 
              <TextInput placeholder="CPR*" value={this.state.cpr2} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpr2 => this.setState({ cpr2 })} underlineColorAndroid='transparent' /> 
              <TextInput placeholder="CPM*" value={this.state.cpm2} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpm2 => this.setState({ cpm2 })} underlineColorAndroid='transparent' /> 
            </View> 
            <View style={styles.SwitchOuterSectionStyle}> 
              <Text style={styles.textViewContainer}>C-Default(0.5,0.5) </Text> 
              <TextInput placeholder="CPR*" value={this.state.cpr3} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpr3 => this.setState({ cpr3 })} underlineColorAndroid='transparent' /> 
              <TextInput placeholder="CPM*" value={this.state.cpm3} style={styles.TextInputStyleClass} editable={this.state.bud} keyboardType='numeric' onChangeText={cpm3 => this.setState({ cpm3 })} underlineColorAndroid='transparent' /> 
            </View> 
            <View style={styles.SwitchOuterSectionStyle}> 
              <Text style={styles.textViewContainer}>D(0.25,0.25)</Text> 
              <TextInput placeholder="CPR*" value={this.state.cpr4} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpr4 => this.setState({ cpr4 })} underlineColorAndroid='transparent' /> 
              <TextInput placeholder="CPM*" value={this.state.cpm4} style={styles.TextInputStyleClass} editable={this.state.bud} keyboardType='numeric' onChangeText={cpm4 => this.setState({ cpm4 })} underlineColorAndroid='transparent' /> 
            </View> 
            <View style={styles.SwitchOuterSectionStyle}> 
              <Text style={styles.textViewContainer}>E(0,0)</Text> 
              <TextInput placeholder="CPR*" value={this.state.cpr5} style={styles.TextInputStyleClass} keyboardType='numeric' onChangeText={cpr5 => this.setState({ cpr5 })} underlineColorAndroid='transparent' /> 
              <TextInput placeholder="CPM*" value={this.state.cpm5} style={styles.TextInputStyleClass} editable={this.state.bud} keyboardType='numeric' onChangeText={cpm5 => this.setState({ cpm5 })} underlineColorAndroid='transparent' /> 
            </View> 
            <TouchableOpacity style={styles.SubmitButtonStyle} activeOpacity={.5} onPress={this.onSaveDataSlabs} > 
              <Text style={styles.TextStyle}> SAVE </Text> 
            </TouchableOpacity> 
          </View>
        </ScrollView>
      </ScrollView>
    </View> 
  ); 
} 

const styles = StyleSheet.create({ 
  MainContainerViewCamp: { 
    flex: 1, // 添加flex:1让容器占满屏幕
    justifyContent: 'center', 
    paddingTop: (Platform.OS === 'ios') ? 20 : 30, 
    padding: 5, 
  }, 
  SwitchOuterSectionStyle: { 
    flexDirection: 'row', 
    padding: 4, 
    justifyContent: 'center', 
    alignItems: 'center' 
  }, 
  textViewContainer: { 
    padding: 7, 
    fontSize: 17, 
    width: 150, 
  }, 
  TextInputStyleClass: { 
    textAlign: 'left', 
    paddingLeft: 7, 
    margin: 10, 
    width: 150, 
    height: 40, 
    borderWidth: 1, 
    borderColor: '#00BCD4', 
  }, 
  listViewStyle: { 
    borderWidth: 1, 
    height: 360, 
    borderColor: '#87ceeb', 
  }, 
  SubmitButtonStyle: { 
    marginTop: 10, 
    paddingTop: 15, 
    paddingBottom: 15, 
    backgroundColor: '#00BCD4', 
    borderRadius: 10, 
    borderWidth: 1, 
    borderColor: '#fff',
    marginHorizontal: 10 // 给按钮添加左右边距,避免贴边
  }, 
  TextStyle: { 
    color: '#fff', 
    textAlign: 'center', 
  } 
});

关键修改点说明

  1. 嵌套ScrollView结构:外层垂直ScrollView负责上下滚动,内层水平ScrollView负责左右滚动,这样就实现了双向滚动效果
  2. 添加垂直容器:在水平ScrollView内部新增了一个flexDirection: 'column'的View,让所有SwitchOuterSectionStyle区块垂直排列,解决了之前挤在一行的问题
  3. 样式调整:给MainContainerViewCamp添加了flex:1,确保容器占满屏幕;给SubmitButtonStyle添加了左右边距,提升视觉体验
  4. 保留双向滚动开关:保留了directionalLockEnabled={false},允许用户同时进行水平和垂直滚动操作

这样修改后,你的每个数据区块会垂直排列,整个页面既可以上下滚动(当区块过多时),也可以左右滚动(当单区块内容过宽时),完全符合你的需求。

内容的提问来源于stack exchange,提问作者hitttt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:12:20