import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:go_router/go_router.dart'; import 'package:new_learn/core/api/class/api.dart'; import 'package:new_learn/core/api/class/model.dart'; import 'package:new_learn/features/class/widgets/post_list_body.dart'; /// ============================================================ /// 【MyInteractPage】「我的互动」页 —— 对标 Vue pages/classPackage/myInteract/myInteract.vue /// /// 一、入口:从「我的」页等进入。 /// 二、结构:NavBar("我的互动") + 3 颗胶囊 tab + 内容区 /// 「我的动态 / 我的点赞 / 我的留言」 /// 三、子列表用通用 PostListBody: /// 动态 getUserClassPost(queryType=0);点赞 getMyLikePage;留言 getMyCommentPage。 /// 点赞页取消点赞时从列表移除该项(removeOnUnlike);其余保留。 /// 四、懒加载:默认建第一个 tab,切到再建(对标 renderedTabs)。 /// ============================================================ class MyInteractPage extends StatefulWidget { const MyInteractPage({super.key}); @override State createState() => _MyInteractPageState(); } class _MyInteractPageState extends State { static const List _tabs = ['我的动态', '我的点赞', '我的留言']; int _currentTab = 0; final List _loadedTabs = [true, false, false]; void _switchTab(int index) { if (_currentTab == index) return; setState(() { _loadedTabs[index] = true; _currentTab = index; }); } void _openDetail(UserPostDto post) { context.push('/class/my-update-detail', extra: post); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F8FA), appBar: AppBar( backgroundColor: const Color(0xFFF5F8FA), elevation: 0, title: const Text( '我的互动', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w400, color: Color(0xFF1D2B47), ), ), centerTitle: true, leading: IconButton( icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2B47)), onPressed: () => context.canPop() ? context.pop() : context.go('/class'), ), ), body: Column( children: [ _buildTabs(), Expanded( child: IndexedStack( index: _currentTab, children: [ if (_loadedTabs[0]) _UpdateTab(onTapPost: _openDetail), if (_loadedTabs[1]) _LikeTab(onTapPost: _openDetail), if (_loadedTabs[2]) _CommentTab(onTapPost: _openDetail), ], ), ), ], ), ); } Widget _buildTabs() { return Container( width: double.infinity, padding: EdgeInsets.fromLTRB(14.w, 12.h, 14.w, 22.h), child: Row( children: [ for (int i = 0; i < _tabs.length; i++) ...[ if (i > 0) SizedBox(width: 12.w), _buildTabItem(i), ], ], ), ); } Widget _buildTabItem(int index) { final active = _currentTab == index; return GestureDetector( onTap: () => _switchTab(index), child: Container( width: 84.w, height: 37.h, alignment: Alignment.center, decoration: BoxDecoration( color: active ? const Color(0xFF3D7DF5) : Colors.white, borderRadius: BorderRadius.circular(20.r), ), child: Text( _tabs[index], style: TextStyle( fontSize: 15, color: active ? Colors.white : const Color(0xFF687FAD), ), ), ), ); } } class _UpdateTab extends StatelessWidget { const _UpdateTab({required this.onTapPost}); final ValueChanged onTapPost; @override Widget build(BuildContext context) { return PostListBody( fetchPage: ({required pageIndex, required pageSize, required prevPageId}) => ClassApi.instance.getUserClassPost( queryType: 0, pageIndex: pageIndex, pageSize: pageSize, prevPageId: prevPageId, ), emptyText: '暂无动态', onTapPost: onTapPost, ); } } class _LikeTab extends StatelessWidget { const _LikeTab({required this.onTapPost}); final ValueChanged onTapPost; @override Widget build(BuildContext context) { return PostListBody( fetchPage: ({required pageIndex, required pageSize, required prevPageId}) => ClassApi.instance.getMyLikePage( pageIndex: pageIndex, pageSize: pageSize, prevPageId: prevPageId, ), emptyText: '暂无点赞', removeOnUnlike: true, onTapPost: onTapPost, ); } } class _CommentTab extends StatelessWidget { const _CommentTab({required this.onTapPost}); final ValueChanged onTapPost; @override Widget build(BuildContext context) { return PostListBody( fetchPage: ({required pageIndex, required pageSize, required prevPageId}) => ClassApi.instance.getMyCommentPage( pageIndex: pageIndex, pageSize: pageSize, prevPageId: prevPageId, ), emptyText: '暂无留言', onTapPost: onTapPost, ); } }