import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:loopin/api/shop_api.dart'; import 'package:loopin/service/http.dart'; /// 单个 Tab 的状态 class TabState { final ScrollController scrollController; final RxInt currentPage; final RxDouble scrollOffset; final RxList dataList; final RxBool isLoading; final RxBool hasLoaded; TabState({ required this.scrollController, required this.currentPage, required this.scrollOffset, required this.dataList, required this.isLoading, required this.hasLoaded, }); } class ShopIndexController extends GetxController with GetSingleTickerProviderStateMixin { TabController? tabController; ///轮播图数据 RxList swiperData = [].obs; /// tab 分类列表 RxList tabList = [].obs; /// 每个 tab 对应的状态 final Map tabs = {}; /// 当前 tab index RxInt currentTabIndex = 0.obs; /// 初始化 Tab 分类 void initTabs({required TickerProvider vsync}) async { // 释放旧的 ScrollController tabs.forEach((_, state) => state.scrollController.dispose()); tabs.clear(); tabList.clear(); // 先释放旧 TabController(并移除监听) tabController?.removeListener(_tabListener); tabController?.dispose(); // 赋值 tab 数据 final res = await Http.post(ShopApi.shopCategory, data: { 'level': 1, }); final data = res['data'] as List; // logger.w(data); tabList.addAll(data); // 初始化每个 tab 的状态 for (int i = 0; i < tabList.length; i++) { final controller = ScrollController(); tabs[i] = TabState( scrollController: controller, currentPage: 1.obs, scrollOffset: 0.0.obs, dataList: [].obs, isLoading: false.obs, hasLoaded: false.obs, ); } // 创建新的 TabController tabController = TabController(length: tabList.length, vsync: vsync); tabController?.addListener(_tabListener); // 初始化第一个 tab 的数据 if (tabList.isNotEmpty) { loadSwiperData(); loadData(0); } } /// Tab 切换监听 void _tabListener() { if (!tabController!.indexIsChanging) { currentTabIndex.value = tabController!.index; final tab = tabs[currentTabIndex.value]; if (tab != null && !tab.hasLoaded.value) { loadData(currentTabIndex.value); } } } Future refreshData(int index) async { await loadSwiperData(); final tab = tabs[index]; if (tab == null) return; tab.currentPage.value = 1; tab.dataList.clear(); tab.isLoading.value = false; tab.hasLoaded.value = false; await loadData(index); } /// 加载pageview数据 Future loadData(int index) async { final tab = tabs[index]; if (tab == null || tab.isLoading.value) return; tab.isLoading.value = true; final res = await Http.post(ShopApi.shopList, data: { 'size': 10, 'current': tab.currentPage.value, 'categoryId': tabList[index]['id'], }); final data = res['data']['records']; tab.dataList.addAll(data); // logger.w(res); tab.currentPage.value += 1; tab.isLoading.value = false; tab.hasLoaded.value = true; } /// 加载swiper数据 Future loadSwiperData() async { final res = await Http.post(ShopApi.shopSwiperList, data: { 'type': 1, }); final data = res['data']; // logger.w(res); swiperData.assignAll(data); } @override void onClose() { tabController?.removeListener(_tabListener); tabs.forEach((_, state) => state.scrollController.dispose()); super.onClose(); } }