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

Flutter切换Tab时如何保留内容?数据丢失问题求助

问题分析与解决方案

核心问题

  1. 页面状态丢失:你的historial是State类的局部变量,当切换Tab时,默认情况下TabBarView会销毁非当前页面的State,导致historial被重新初始化为空列表,历史记录丢失。
  2. 列表项显示错误:ListTile的title错误使用了context.watch<ItemProvider>().product.descripcion,导致所有历史记录项显示同一个产品名称,而不是当前遍历的产品。

解决方案

方案一:用Provider全局管理历史记录(推荐,支持跨页面共享)

将historial移到ItemProvider中维护,确保数据不受页面重建影响。

  1. 修改ItemProvider:
class ItemProvider with ChangeNotifier {
  Product _product = Product(
    fotoUrl: '',
    itemId: 0,
    codItem: '',
    descripcion: '',
    monedaId: 0,
    precioVentaActual: 0,
    existenciaActual: 0,
    precioIvaIncluido: 0,
    existenciaTotal: 0,
    ivaId: 0,
    valor: 0,
  );
  List<Product> _historial = [];

  Product get product => _product;
  List<Product> get historial => _historial;

  void setProduct(Product product) {
    _product = product;
    notifyListeners();
  }

  void addToHistorial(Product product) {
    // 避免重复添加相同产品
    final exists = _historial.indexWhere((p) => p.codItem == product.codItem);
    if (exists == -1) {
      _historial.insert(0, product);
    }
    notifyListeners();
  }
}
  1. 修改Busqueda页面:
    移除局部historial变量,直接从Provider获取和更新数据,同时修复列表项显示错误:
import 'package:provider/provider.dart';
import '../../providers/item_provider.dart';
import '../../search/product_search.dart';
import '../../models/product.dart';

class Busqueda extends StatefulWidget {
  final TabController tabController;

  const Busqueda(this.tabController);

  @override
  State<Busqueda> createState() => _BusquedaState();
}

class _BusquedaState extends State<Busqueda> {
  late Product productoSeleccionado = Product(
      fotoUrl: '',
      itemId: 0,
      codItem: '',
      descripcion: '',
      monedaId: 0,
      precioVentaActual: 0,
      existenciaActual: 0,
      precioIvaIncluido: 0,
      existenciaTotal: 0,
      ivaId: 0,
      valor: 0);

  Widget historialProducts(List<Product> products){
    return ListView.builder(
      itemCount: products.length,
      itemBuilder: (context, i){
        final producto = products[i];
        return ListTile(
          // 修复:显示当前遍历的产品名称
          title: Text(producto.descripcion),
          subtitle: Text(producto.codItem),
          trailing: Text(producto.precioVentaActual.toString()),
        );
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    final itemProvider = context.watch<ItemProvider>();
    return Center(
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: SearchBar(
              hintText: itemProvider.product.descripcion.isEmpty 
                  ? 'Buscar producto' 
                  : itemProvider.product.descripcion,
              textStyle: const MaterialStatePropertyAll(TextStyle(color: Colors.grey)),
              onTap: () async {
                final producto = await showSearch(
                    context: context,
                    delegate: ProductSearchDelegate('Buscar Producto', itemProvider.historial));
                if (producto != null) {
                  setState(() {
                    productoSeleccionado = producto;
                  });
                  itemProvider.setProduct(producto);
                  itemProvider.addToHistorial(producto);
                  widget.tabController.animateTo(2);
                }
              },
            ),
          ),
          Expanded(
            child: historialProducts(itemProvider.historial)
          )
        ],
      ),
    );
  }
}

方案二:保持页面State不销毁(仅适合单页面状态保留)

如果不需要跨页面共享历史记录,可通过AutomaticKeepAliveClientMixin让页面切换时保留State:

class _BusquedaState extends State<Busqueda> with AutomaticKeepAliveClientMixin {
  // ... 原有代码 ...

  // 重写该方法,返回true
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    // 必须调用super.build(context)
    super.build(context);
    // ... 原有build代码 ...
  }
}

额外优化建议

  • 给SearchBar设置默认提示文本,避免初始状态下hintText为空。
  • 可在ItemProvider中添加清空历史记录的方法,增强功能完整性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:43:24