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

Flutter组件间变量同步问题:TabScanning与MapPage的x/y值更新异常

问题描述

我需要在TabScanning组件中持续更新x和y值,并在MapPage组件中使用这些更新后的值。在TabScanning页面打印x和y时,数值已更新,但MapPage中的值始终保持0.0。

TabScanning组件代码

class TabScanning extends StatefulWidget {
  double x = 0, y = 0;
}

class _TabScanningState extends State<TabScanning> {

  initScanBeacon() async {
    await flutterBeacon.initializeScanning;
        ..
        ...
        setState(() {
        ..
        ...
            widget.x = (c * e - f * b);
            widget.x = widget.x / (e * a - b * d);

            widget.y = (c * d - a * f);
            widget.y = widget.y / (b * d - a * e);
        });
      }
    });
  }
}

MapPage组件代码

class _MapPageState extends State<MapPage> {

  TabScanning bec = TabScanning();
  double x = 0;
  double y = 0;
  Offset location = const Offset(0, 0);

  @override
  void initState() {
    super.initState();
    Timer.periodic(const Duration(milliseconds: 20), (timer) {
      setState(() {
        x = bec.x;
        y = bec.y;
        location = Offset(x,y);
      });
    });
  }
}
问题原因

你在_MapPageState中创建的TabScanning bec = TabScanning();是一个全新的独立实例,和实际负责扫描的TabScanning组件不是同一个对象。这个新实例的x、y值永远是初始的0.0,自然拿不到扫描组件里的更新数据。

解决方案

下面提供几种实用的解决方式,根据你的组件层级和复杂度选择:

方案1:回调函数(适合父子/近邻组件)

如果两个组件有直接的父子关系,或者在同一个父组件下,用回调传递值最直接:

修改TabScanning组件

添加回调参数,在计算出x、y后触发回调:

class TabScanning extends StatefulWidget {
  // 定义回调函数,用于传递更新后的坐标
  final Function(double x, double y) onLocationUpdated;

  const TabScanning({super.key, required this.onLocationUpdated});

  @override
  _TabScanningState createState() => _TabScanningState();
}

class _TabScanningState extends State<TabScanning> {
  initScanBeacon() async {
    await flutterBeacon.initializeScanning;
    // ... 扫描逻辑省略
    setState(() {
      // 计算x、y值
      double calculatedX = (c * e - f * b) / (e * a - b * d);
      double calculatedY = (c * d - a * f) / (b * d - a * e);
      // 通过回调传递给父组件
      widget.onLocationUpdated(calculatedX, calculatedY);
    });
  }
}

修改MapPage组件

接收回调并更新自身状态:

class _MapPageState extends State<MapPage> {
  double x = 0;
  double y = 0;
  Offset location = const Offset(0, 0);

  @override
  Widget build(BuildContext context) {
    return TabScanning(
      onLocationUpdated: (newX, newY) {
        setState(() {
          x = newX;
          y = newY;
          location = Offset(x, y);
        });
      },
    );
    // ... 其他UI代码
  }
}

方案2:全局状态管理(适合跨层级组件)

如果组件层级较深,没有直接关联,用状态管理工具(比如Provider)更可靠:

  1. 添加Provider依赖到pubspec.yaml:
dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5
  1. 创建状态模型类:
import 'package:flutter/foundation.dart';

class LocationModel extends ChangeNotifier {
  double _x = 0;
  double _y = 0;

  double get x => _x;
  double get y => _y;

  void updateLocation(double newX, double newY) {
    _x = newX;
    _y = newY;
    notifyListeners(); // 通知所有监听组件更新
  }
}
  1. 在应用顶层注册模型:
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => LocationModel(),
      child: const MyApp(),
    ),
  );
}
  1. 修改TabScanning更新状态:
class _TabScanningState extends State<TabScanning> {
  initScanBeacon() async {
    await flutterBeacon.initializeScanning;
    // ... 扫描逻辑省略
    setState(() {
      double calculatedX = (c * e - f * b) / (e * a - b * d);
      double calculatedY = (c * d - a * f) / (b * d - a * e);
      // 更新全局状态
      Provider.of<LocationModel>(context, listen: false).updateLocation(calculatedX, calculatedY);
    });
  }
}
  1. 修改MapPage监听状态:
class _MapPageState extends State<MapPage> {
  Offset location = const Offset(0, 0);

  @override
  Widget build(BuildContext context) {
    // 监听全局状态变化,自动更新UI
    final locationModel = Provider.of<LocationModel>(context);
    location = Offset(locationModel.x, locationModel.y);
    
    return // ... 你的地图UI代码
  }
}

方案3:单例模式(适合简单场景)

如果只是简单的数值传递,也可以用单例,但不推荐用于复杂状态场景:

// 单例服务类
class LocationService {
  static final LocationService _instance = LocationService._internal();
  factory LocationService() => _instance;
  LocationService._internal();

  double x = 0;
  double y = 0;

  void update(double newX, double newY) {
    x = newX;
    y = newY;
  }
}

在TabScanning中更新:

// 计算出x、y后调用
LocationService.instance.update(calculatedX, calculatedY);

在MapPage中定时获取:

class _MapPageState extends State<MapPage> {
  double x = 0;
  double y = 0;
  Offset location = const Offset(0, 0);

  @override
  void initState() {
    super.initState();
    Timer.periodic(const Duration(milliseconds: 20), (timer) {
      setState(() {
        x = LocationService.instance.x;
        y = LocationService.instance.y;
        location = Offset(x, y);
      });
    });
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:05:00