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

Flutter技术问题:如何从ListTile更新ListView或删除列表项?

仓库车辆进出管理Flutter应用列表更新问题

我开发了一款仓库车辆进出管理的简易Flutter应用,从独立数据库获取车辆数据并通过ListView.separated展示列表。当保安选中某辆车,完成信息核验、拍照并将照片上传至数据库后,需要更新ListView中的车辆列表。现需实现从CarTile的回调中调用CarsListScreen的_loadCarsList方法,或直接删除当前列表项。

现有代码:

car_list_screen.dart

import 'package:flutter/material.dart';
import 'package:storage_security/car_tile.dart';
import 'package:storage_security/cars_repository.dart';
import 'package:storage_security/theme.dart';
import 'car.dart';

class CarsListScreen extends StatefulWidget {
  const CarsListScreen({super.key});

  @override
  State<StatefulWidget> createState() => _CarsListScreenState();
}

class _CarsListScreenState extends State<CarsListScreen> {
  List<Car>? _carsList;
  bool carsFromStorage = false;

  @override
  void initState() {
    _loadCarsList();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(carsFromStorage ? 'OUT' : 'IN'),),
      body: (_carsList == null)
          ? const Center(child: CircularProgressIndicator())
          : _carsList!.isEmpty ? const Center(child: Text('No data')) :
            ListView.separated(
              padding: const EdgeInsets.only(top: 14),
              separatorBuilder: (context, index) => const Divider(),
              itemCount: _carsList!.length,
              itemBuilder: (context, i) {
                return CarTile(car: _carsList![i]);
          },
      ),
      bottomNavigationBar: BottomAppBar(
        color: darkTheme.appBarTheme.backgroundColor,
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            IconButton(onPressed: (){
                carsFromStorage = false;
                _loadCarsList();
              }, icon: Image.asset('assets/images/green_arrow.png'), iconSize: 48,),
            IconButton(onPressed: (){
                carsFromStorage = true;
                _loadCarsList();
             }, icon: Image.asset('assets/images/red_arrow.png'), iconSize: 48,),
          ],
        ),
      ),
    );
  }

  Future<void>? _loadCarsList() async {
    _carsList = null; // for CircularProgressIndicator
    setState(() {});

    _carsList = await CarsRepository().getCarList(carsFromStorage);
    setState(() {});
  }
}

car_tile.dart

import 'package:flutter/material.dart';
import 'car.dart';

class CarTile extends StatelessWidget {
  const CarTile({
    super.key,
    required this.car,
  });

  final Car car;
  final toEvent = const Image(image: AssetImage('assets/images/event.png'));
  final toStorage = const Image(image: AssetImage('assets/images/storage.png'));

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return ListTile(
        leading: car.isShipment ? toEvent : toStorage,
        title: Text(car.car, style: theme.textTheme.bodyMedium),
        subtitle: Text(car.driver, style: theme.textTheme.labelSmall,),
        trailing: const Icon(Icons.arrow_forward_ios),
        onTap: () async {
          final result = await Navigator.of(context).pushNamed(
            '/car',
            arguments: car,
          );

          if (result == true) {
            // >>>> 重新加载车辆列表或删除当前列表项 <<<<
          }
        }
    );
  }
}

解决方案

方案一:触发父组件重新加载列表

通过给CarTile添加回调函数,在操作完成后通知CarsListScreen调用_loadCarsList刷新数据,保证列表与数据库状态一致。

  1. 修改CarTile,添加回调参数
import 'package:flutter/material.dart';
import 'car.dart';

class CarTile extends StatelessWidget {
  const CarTile({
    super.key,
    required this.car,
    required this.onCompleted, // 添加回调参数
  });

  final Car car;
  final VoidCallback onCompleted; // 定义回调类型
  final toEvent = const Image(image: AssetImage('assets/images/event.png'));
  final toStorage = const Image(image: AssetImage('assets/images/storage.png'));

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return ListTile(
        leading: car.isShipment ? toEvent : toStorage,
        title: Text(car.car, style: theme.textTheme.bodyMedium),
        subtitle: Text(car.driver, style: theme.textTheme.labelSmall,),
        trailing: const Icon(Icons.arrow_forward_ios),
        onTap: () async {
          final result = await Navigator.of(context).pushNamed(
            '/car',
            arguments: car,
          );

          if (result == true) {
            onCompleted(); // 触发回调通知父组件刷新
          }
        }
    );
  }
}
  1. 在CarsListScreen中传递回调
    修改itemBuilder部分:
itemBuilder: (context, i) {
  return CarTile(
    car: _carsList![i],
    onCompleted: () {
      _loadCarsList(); // 调用加载方法刷新列表
    },
  );
},

方案二:直接删除当前列表项

如果确认操作后该车辆无需再显示,可以直接从本地列表移除,提升界面响应速度。

  1. 修改CarTile,添加索引和删除回调
import 'package:flutter/material.dart';
import 'car.dart';

class CarTile extends StatelessWidget {
  const CarTile({
    super.key,
    required this.car,
    required this.index,
    required this.onItemRemoved, // 添加删除回调
  });

  final Car car;
  final int index;
  final Function(int) onItemRemoved;
  final toEvent = const Image(image: AssetImage('assets/images/event.png'));
  final toStorage = const Image(image: AssetImage('assets/images/storage.png'));

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return ListTile(
        leading: car.isShipment ? toEvent : toStorage,
        title: Text(car.car, style: theme.textTheme.bodyMedium),
        subtitle: Text(car.driver, style: theme.textTheme.labelSmall,),
        trailing: const Icon(Icons.arrow_forward_ios),
        onTap: () async {
          final result = await Navigator.of(context).pushNamed(
            '/car',
            arguments: car,
          );

          if (result == true) {
            onItemRemoved(index); // 通知父组件删除对应项
          }
        }
    );
  }
}
  1. 在CarsListScreen中处理删除逻辑
    修改itemBuilder部分:
itemBuilder: (context, i) {
  return CarTile(
    car: _carsList![i],
    index: i,
    onItemRemoved: (index) {
      setState(() {
        _carsList!.removeAt(index); // 直接删除列表项并更新状态
      });
    },
  );
},

方案选择建议

  • 方案一更适合需要严格同步数据库状态的场景(比如有其他设备或操作同时修改数据)
  • 方案二响应更快,但需确保数据库中已完成对应车辆的状态更新,避免下次加载时数据重复出现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:02:32