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

React Native问题:ScrollView安卓模拟器失效,Web端正常

React Native安卓端ScrollView无法滚动问题排查与修复

问题描述

使用Expo开发React Native页面,点击黄色区域会展开青蓝色背景的列表。页面内容被ScrollView包裹,但当内容超出屏幕范围时,安卓模拟器无法滚动,Web端运行正常。

问题原因及修复方案

1. 相对定位导致布局计算异常

InventoryItemDisplayRow的展开菜单View使用position: relative+bottom: 25,这种方式会让元素在文档流中保留原始占位,同时视觉上向上偏移,导致ScrollView无法正确计算实际内容高度,安卓端无法识别可滚动区域。

修复:用marginTop: -25替代position: relative+bottom: 25,既实现视觉偏移效果,又不会干扰ScrollView的高度计算逻辑。

2. 外层容器高度设置冲突

InventorySummaryPage中外层View同时设置flex:1和height: "auto",安卓端布局优先级会出现冲突,导致ScrollView无法获取正确的可用高度。

修复:移除height: "auto",仅保留flex:1,让外层View自动填充父容器高度,确保ScrollView能正确识别滚动边界。

3. 尺寸获取方式不统一

部分组件混用Dimensions.get("screen")和Dimensions.get("window"),安卓端screen尺寸包含状态栏等系统区域,会导致元素尺寸计算偏差,间接影响滚动判断。

修复:将所有Dimensions.get("screen")替换为Dimensions.get("window"),保证全页面尺寸计算标准统一。

修改后的代码

InventorySummaryPage.js

import { Component } from "react";
import { Dimensions, View } from "react-native";
import ImageButton from "../../../base/ImageButton/ImageButton";
import icons from "../../../../assets/icons/ImageAssets";
import InventoryItemDisplayRow from "./InventoryItemDisplayRow";
import { ScrollView } from "react-native";

export default class InventorySummaryPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            locationContent: {}
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if(this.props.showInventoryPage === "summary" &&
           this.props.showInventoryPage != prevProps.showInventoryPage) {
            this.filterContent()
        }
    }

    filterContent() {
        let itemsInLocation = this.props.inventorySummary.filter((elem) => (elem.location == this.props.locationSelected))
        let itemsGroups = {}
        itemsInLocation.forEach((item) => {
            if(itemsGroups[item.itemId]) {
                itemsGroups[item.itemId].totalWeight += item.itemWeight ? item.itemWeight * item.itemQuantity : 0,
                itemsGroups[item.itemId].totalQuantity += Number(item.itemQuantity),
                itemsGroups[item.itemId].content.push({
                    id: item.id,
                    quantity: item.itemQuantity,
                    weight: item.itemWeight,
                    comment: item.comment
                })
            } else {
                itemsGroups[item.itemId] = {
                    name: item.itemName,
                    totalWeight: item.itemWeight ? item.itemWeight * item.itemQuantity : 0,
                    totalQuantity: Number(item.itemQuantity),
                    content: [{
                        id: item.id,
                        quantity: item.itemQuantity,
                        weight: item.itemWeight,
                        comment: item.comment
                    }]
                }
            }
        });
        this.setState({locationContent: itemsGroups})
    }

    checkFilterComments() {}

    render() {
        return (
            <View style={{
                display: this.props.showInventoryPage === "summary" ? "flex" : "none",
                width: Dimensions.get("window").width,
                flex: 1
            }}>
                <ScrollView contentContainerStyle={{alignItems: "center"}}>
                    <ImageButton 
                        onClick={this.props.showAddItemPage}
                        style={{
                            width: Dimensions.get("window").width * 0.8,
                            padding: 0,
                            marginVertical: 5
                        }}
                        iconImage={icons.add_icon} 
                        label={"Add a new item"}
                    />
                    {
                    Object.keys(this.state.locationContent).map((key) => {
                        let item = this.state.locationContent[key]
                        return(
                        <InventoryItemDisplayRow
                            key={key} 
                            content={item}
                        />
                        )
                    })
                    }
                </ScrollView>
            </View>
        )
    }
}

InventoryItemDisplayRow.js

import { Component } from "react";
import { View } from "react-native";
import InventoryItemDisplayRowInner from "./InventoryItemDisplayRowInner";
import { Text } from "react-native";
import ImageButton from "../../../base/ImageButton/ImageButton";
import { Pressable } from "react-native";
import { Dimensions } from "react-native";
import InventoryPageStyles from "../resources/InventoryPageStyles";
import { Shadow } from "react-native-shadow-2";

export default class InventoryItemDisplayRow extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showInnerMenu: false
    };
  }

  openMenu = () => {
    this.setState((prevState) => ({
      showInnerMenu: !prevState.showInnerMenu
    }));
  };

  render() {
    return (
      <View style={this.props.style}>
        <Pressable style={{zIndex: 2,}} onPress={this.openMenu}>
          <Shadow 
            distance={1} 
            startColor={'#0005'} 
            offset={[1, 3]}
          >
            <View
            style={{
                display: "flex",
                flexDirection: "row",
                borderRadius: 20,
                borderWidth: 2,
                borderStyle: "solid",
                borderColor: "black",
                width: Dimensions.get("window").width * 0.9,
                paddingVertical: 5,
                paddingHorizontal: 15,
                height: Dimensions.get("window").height * 0.06,
                alignItems: "center",
                position: "relative",
                backgroundColor: "yellow",
                marginBottom: 10
            }}
            >
            <Text
                style={[{
                height: Dimensions.get("window").width * 0.1,
                width: Dimensions.get("window").width * 0.1,
                borderWidth: 2,
                borderStyle: "solid",
                borderColor: "black",
                borderRadius: 15
                }, InventoryPageStyles.inventoryItemCardQuantity]}
            >
                {this.props.content.totalQuantity}
            </Text>
            <View
                style={{
                marginVertical: 0,
                marginHorizontal: 15,
                width: Dimensions.get("window").width * 0.4,
                textAlign: "left",
                verticalAlign: "top"
                }}
            >
                <Text style={InventoryPageStyles.inventoryItemCardMainName}>{this.props.content.name}</Text>
                <Text>{this.props.desc}</Text>
            </View>
            <Text style={InventoryPageStyles.inventoryItemCardWeight}>{this.props.content.totalWeight}</Text>
            </View>
        </Shadow>
        </Pressable>

        <View
          style={{
            display: this.state.showInnerMenu ? "block" : "none",
            marginLeft: Dimensions.get("window").width * 0.1,
            width: Dimensions.get("window").width * 0.8,
            borderStyle: "solid",
            borderColor: "black",
            borderRadius: 15,
            borderTopRightRadius: 0,
            paddingVertical: 5,
            paddingHorizontal: 15,
            backgroundColor: "lightblue",
            marginTop: -25,
            zIndex: 1,
            paddingTop: 30
          }}
        >
          {this.props.content.content.map((item) => (
            <InventoryItemDisplayRowInner 
              key={item.id}
              name={item.comment} 
              weight={item.weight}
              quantity={item.quantity}
            />
          ))}
          <ImageButton label={"SAVE"}/>
        </View>
      </View>
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:22:32