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

React Native:ScrollView嵌套FlatList实现整体滚动的正确方法

如何实现整个区块的滚动效果?

我希望整个区块能够实现滚动效果,尝试了多种方法均未成功:将顶部视图移入ListHeaderComponent无效,启用FlatList的nestedScrollEnabled属性也无作用。以下是我的代码演变,请问正确的滚动实现方案是什么?

原代码

const renderAccordians = () => {
    const items: JSX.Element[] = [];
    areaData.forEach(item => {
      items.push(<Accordian item={item} key={item.title} />);
    });
    return items;
  };

当前代码

return (
    <View>
      <View style={styles.row}>
        <TouchableOpacity onPress={() => onClickFather()}>
          <MaterialIcons size={24} name={data.checked ? 'check-box' : 'check-box-outline-blank'} color={'black'} />
        </TouchableOpacity>
        <Text style={[styles.title]}>{data.title}</Text>
        <TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
          <MaterialIcons name={expanded ? 'arrow-drop-up' : 'arrow-drop-down'} size={30} color={'black'} />
        </TouchableOpacity>
      </View>
      <View style={styles.parentHr} />
      {expanded && (
        <FlatList
          data={data.data}
          numColumns={1}
          scrollEnabled={false}
          renderItem={({ item, index }) => (
            <View>
              <TouchableOpacity style={[styles.childRow, styles.button]} onPress={() => onClick(index)}>
                <MaterialIcons
                  size={24}
                  name={item.checked ? 'check-box' : 'check-box-outline-blank'}
                  color={'black'}
                />
                <Text style={[styles.itemInActive]}>{item.key}</Text>
              </TouchableOpacity>
              <View style={styles.childHr} />
            </View>
          )}
        />
      )}
    </View>
  );

正确实现方案

你的问题核心是内部FlatList禁用了滚动,且整个外层没有可滚动容器,导致无法触发滚动。下面提供两种可行的修改方案:

方案一:用ScrollView包裹整个区块

把最外层的<View>换成<ScrollView>,同时移除内部FlatList的scrollEnabled={false}(或者直接用map渲染子项,单列场景下没必要用FlatList):

return (
  <ScrollView style={{ flex: 1 }}>
    <View style={styles.row}>
      <TouchableOpacity onPress={() => onClickFather()}>
        <MaterialIcons size={24} name={data.checked ? 'check-box' : 'check-box-outline-blank'} color={'black'} />
      </TouchableOpacity>
      <Text style={[styles.title]}>{data.title}</Text>
      <TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
        <MaterialIcons name={expanded ? 'arrow-drop-up' : 'arrow-drop-down'} size={30} color={'black'} />
      </TouchableOpacity>
    </View>
    <View style={styles.parentHr} />
    {expanded && (
      <View>
        {data.data.map((item, index) => (
          <View key={index}>
            <TouchableOpacity style={[styles.childRow, styles.button]} onPress={() => onClick(index)}>
              <MaterialIcons
                size={24}
                name={item.checked ? 'check-box' : 'check-box-outline-blank'}
                color={'black'}
              />
              <Text style={[styles.itemInActive]}>{item.key}</Text>
            </TouchableOpacity>
            <View style={styles.childHr} />
          </View>
        ))}
      </View>
    )}
  </ScrollView>
);

方案二:让FlatList包含头部统一处理滚动

如果坚持用FlatList,把顶部标题栏设为ListHeaderComponent,同时确保FlatList占满可滚动空间,不要禁用滚动:

return (
  <FlatList
    data={expanded ? data.data : []}
    ListHeaderComponent={
      <>
        <View style={styles.row}>
          <TouchableOpacity onPress={() => onClickFather()}>
            <MaterialIcons size={24} name={data.checked ? 'check-box' : 'check-box-outline-blank'} color={'black'} />
          </TouchableOpacity>
          <Text style={[styles.title]}>{data.title}</Text>
          <TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
            <MaterialIcons name={expanded ? 'arrow-drop-up' : 'arrow-drop-down'} size={30} color={'black'} />
          </TouchableOpacity>
        </View>
        <View style={styles.parentHr} />
      </>
    }
    renderItem={({ item, index }) => (
      <View>
        <TouchableOpacity style={[styles.childRow, styles.button]} onPress={() => onClick(index)}>
          <MaterialIcons
            size={24}
            name={item.checked ? 'check-box' : 'check-box-outline-blank'}
            color={'black'}
          />
          <Text style={[styles.itemInActive]}>{item.key}</Text>
        </TouchableOpacity>
        <View style={styles.childHr} />
      </View>
    )}
    keyExtractor={(item, index) => index.toString()}
    style={{ flex: 1 }}
  />
);

关键注意点

  • 滚动容器(ScrollView/FlatList)必须设置style={{ flex: 1 }},确保它占满父容器的剩余空间;
  • 不要随意设置scrollEnabled={false},除非你明确不需要该容器滚动;
  • 只有嵌套滚动场景(比如外层已有ScrollView)才需要启用nestedScrollEnabled,你的场景优先让最外层作为滚动容器即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:31:02