import 'dart:async'; import 'package:flutter/material.dart'; import 'package:odf/bean/racks_bean.dart'; import 'package:odf/bean/racks_list_bean.dart'; import 'package:odf/tools/machine/machine_details_page.dart'; import 'package:odf/tools/machine/machine_model.dart'; class MachinePage extends StatefulWidget { final String roomId; final String roomName; const MachinePage({super.key, required this.roomId, required this.roomName}); @override State createState() => _MachinePageState(); } class _MachinePageState extends State { late StreamSubscription subscription; final MachineModel _viewmodel = MachineModel(); List racksList = []; int pageNum = 1; // 控制列表滚动 final ScrollController _scrollController = ScrollController(); // 是否正在加载更多 bool _isLoadingMore = false; // 是否还有更多数据 final bool _hasMoreData = true; @override void initState() { // TODO: implement initState super.initState(); // 监听滚动事件,实现上拉加载 _scrollController.addListener(_scrollListener); subscription = _viewmodel.streamController.stream.listen((event) { String code = event['code']; if (code.isNotEmpty) { switch (code) { case 'racksList': RacksBean racksBean = event['data']; racksList.addAll(racksBean.result); break; } } setState(() {}); }); _viewmodel.racksList(pageNum, 20, widget.roomId); } @override void dispose() { // TODO: implement dispose subscription.cancel(); _scrollController.dispose(); super.dispose(); } // 滚动监听 void _scrollListener() { // 判断是否滑到了列表底部 if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 100 && !_isLoadingMore && _hasMoreData) { _loadMoreData(); } } // 下拉刷新数据 Future _refreshData() async { pageNum = 1; racksList.clear(); _viewmodel.racksList(pageNum, 20, widget.roomId); } // 加载更多数据 Future _loadMoreData() async { if (_isLoadingMore) return; setState(() { _isLoadingMore = true; pageNum++; }); _viewmodel.racksList(pageNum, 20, widget.roomId); } @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; final size = MediaQuery.of(context).size; final t10 = size.width / 36; final w25 = size.width / 14.4; final p5 = size.width / 72; final w9 = size.width / 40; final s21 = size.width / 17.142857142857; final t20 = size.width / 18; return Scaffold( backgroundColor: const Color(0xFFD8D8D8), body: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/home_bg.png'), fit: BoxFit.cover, )), child: Column( children: [ Container( margin: EdgeInsets.only(top: statusBarHeight + t10, left: t10, right: t10), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( width: w25, height: w25, padding: EdgeInsets.all(p5), child: Image( width: w9, image: const AssetImage('assets/images/ic_back.png'), ), ), ), Container( alignment: Alignment.center, child: Text( '机房详情', style: TextStyle(fontSize: s21, fontWeight: FontWeight.w600), ), ), Container( width: w25, height: w25, padding: EdgeInsets.all(p5), ), ], ), ), Expanded( child: Container( margin: EdgeInsets.only(top: t20, left: t10, right: t10), child: RefreshIndicator( color: const Color(0xFF1A73EC), onRefresh: _refreshData, child: ListView.builder( controller: _scrollController, padding: const EdgeInsets.all(0), itemCount: racksList.length, itemBuilder: (BuildContext context, int index) { return _item(racksList[index], t10, t20); }), ), )) ], ), ), ); } _item(RacksListBean data, t10, t20) { return GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => MachineDetailsPage( rackId: '${data.id}', dofName: '${data.rackName}', isOpenPop: false, dropId: "", roomName: widget.roomName, ), ), ); }, child: Container( margin: EdgeInsets.only(bottom: t10), child: Card( color: Colors.white, child: Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: t20, top: t20, bottom: t20), child: Text("${data.rackName}"), ), ), ), ); } }