import 'dart:async'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' as extended; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:provider/provider.dart'; import 'package:sport/bean/notice.dart'; import 'package:sport/pages/social/message_list_subpage.dart'; import 'package:sport/pages/social/message_notice_detail_page.dart'; import 'package:sport/provider/message_model.dart'; import 'package:sport/router/navigator_util.dart'; import 'package:sport/router/routes.dart'; import 'package:sport/services/api/inject_api.dart'; import 'package:sport/services/userid.dart'; import 'package:sport/widgets/appbar.dart'; import 'package:sport/widgets/image.dart'; import 'package:sport/widgets/loading.dart'; import 'package:sport/widgets/misc.dart'; import 'package:sport/widgets/persistent_header.dart'; import 'package:sport/widgets/round_tab_indicator.dart'; class MessagePage extends StatefulWidget { @override State createState() => _PageState(); } class _PageState extends State with TickerProviderStateMixin, InjectApi, UserId { late TabController _controller; late Future> _future; @override void initState() { super.initState(); _controller = TabController(length: 3, vsync: this); _future = _getNotice(); } Future> _getNotice() async { List items = []; var resp = await api.getInformList().catchError((onError) {}); items.addAll(resp.pageResult.results ?? []); resp = await api.getNoticeList(isMsg: "0", markread: null); items.addAll(resp.pageResult.results ?? []); return items; } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final double tabHeader = 50; final double statusBarHeight = MediaQuery.of(context).padding.top; final double pinnedHeaderHeight = //statusBar height statusBarHeight + //pinned SliverAppBar height in header kToolbarHeight + tabHeader; return Scaffold( backgroundColor: Colors.white, body: extended.ExtendedNestedScrollView( pinnedHeaderSliverHeightBuilder: () { return pinnedHeaderHeight; }, headerSliverBuilder: (context, innerBoxIsScrolled) { return [ buildSliverAppBar(context, "社区消息", innerBoxIsScrolled: innerBoxIsScrolled), SliverPersistentHeader( delegate: PersistentHeader( min: tabHeader, max: tabHeader, child: Container( color: Colors.white, child: Column( children: [ Expanded( child: Center( child: Container( height: 35, child: TabBar( controller: _controller, isScrollable: true, labelPadding: EdgeInsets.symmetric(horizontal: 32), indicatorWeight: 3, indicatorPadding: EdgeInsets.symmetric(horizontal: 6), indicator: RoundUnderlineTabIndicator(borderSide: BorderSide(color: const Color(0xffFFC400), width: 3)), tabs: [ Tab( text: '聊天', ), Tab( child: Stack( clipBehavior: Clip.none, children: [ Center( child: Text("消息"), ), ValueListenableBuilder( valueListenable: GetIt.I().notifierSocial, builder: (BuildContext context, int value, Widget? child) { int v = value - GetIt.I().notifierMessage.value; if (v == 0) return Container(); return Positioned( right: -4, top: 4, child: Container( width: 8, height: 8, decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.red), ), ); }, ) ], ), ), Tab( text: '通知', ), ], ), ), ), ), Divider( height: 1, indent: 12.0, endIndent: 12.0, ) ], ), )), pinned: true, ), ]; }, body: TabBarView(controller: _controller, children: [ Container(key: const PageStorageKey('Tab1'), child: MessageListSubPage()), ListView.separated( key: const PageStorageKey('Tab2'), padding: EdgeInsets.symmetric(horizontal: 12.0), itemBuilder: (context, index) => index == 0 ? InkWell( onTap: () async { await NavigatorUtil.go(context, "${Routes.socialMessageDetail}?data=comment"); GetIt.I().getCount(); }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 12.0), child: Row(children: [ Image.asset( "lib/assets/img/bbsmessage_icon_color_reply.png", width: 44.0, height: 44.0, ), SizedBox( width: 16.0, ), Expanded( child: Text( "回复我的", style: Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 16), strutStyle: fixedLine, ), ), ValueListenableBuilder( valueListenable: GetIt.I().notifierComment, builder: (BuildContext context, int value, Widget? child) => value == 0 ? Container() : Container( width: 20, height: 20, decoration: BoxDecoration(shape: BoxShape.circle, color: Theme.of(context).accentColor), child: Center( child: Text( value > 99 ? "99+" : "$value", maxLines: 1, style: TextStyle(fontSize: 10, color: Colors.white), ), ), )), SizedBox( width: 8.0, ), arrowRight() ]), )) : index == 1 ? InkWell( onTap: () async { await NavigatorUtil.go(context, "${Routes.socialMessageDetail}?data=like"); GetIt.I().getCount(); }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 12.0), child: Row(children: [ Image.asset( "lib/assets/img/bbsmessage_icon_color_like.png", width: 44.0, height: 44.0, ), SizedBox( width: 16.0, ), Expanded( child: Text( "点赞", style: Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 16), strutStyle: fixedLine, ), ), ValueListenableBuilder( valueListenable: GetIt.I().notifierLike, builder: (BuildContext context, int value, Widget? child) => value == 0 ? Container() : Container( width: 20, height: 20, decoration: BoxDecoration(shape: BoxShape.circle, color: Theme.of(context).accentColor), child: Center( child: Text( value > 99 ? "99+" : "$value", maxLines: 1, style: TextStyle(fontSize: 10, color: Colors.white), ), ), )), SizedBox( width: 8.0, ), arrowRight() ]), )) : Container(), separatorBuilder: (context, index) => Divider( height: 1, ), itemCount: 3, ), Container( key: const PageStorageKey('Tab3'), child: FutureBuilder( future: _future, builder: (_, AsyncSnapshot> snapshot) { if (snapshot.data == null) return RequestLoadingWidget(); return ListView.separated( padding: EdgeInsets.symmetric(horizontal: 12.0), itemBuilder: (context, index) { if (index >= (snapshot.data?.length ?? 0)) return Container(); var item = snapshot.data![index]; return InkWell( onTap: () async { bool result = await NavigatorUtil.goPage(context, (context) => MessageNoticeDetailPage(item)); if (result == true) { item.isRead = 1; } }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 12.0), child: Row(children: [ Image.asset( "lib/assets/img/bbsmessage_icon_color_${(item.type == "rank" || item.type == "receive") ? 'rank' : 'notice'}.png", width: 44.0, height: 44.0, ), SizedBox( width: 8.0, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 18.0, child: Text( "${item.title}", style: Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 16), strutStyle: fixedLine, overflow: TextOverflow.ellipsis, ), ), SizedBox( height: 4, ), Text( "${item.content}", maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyText1!, ) ], ), ), SizedBox( width: 8.0, ), arrowRight() ]), ), ); }, separatorBuilder: (context, index) => Divider( height: 1, ), itemCount: snapshot.data?.length ?? 0 + 1, ); }, ), ) ])), ); } }