123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- 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<StatefulWidget> createState() => _PageState();
- }
- class _PageState extends State<MessagePage> with TickerProviderStateMixin, InjectApi, UserId {
- late TabController _controller;
- late Future<List<Notice>> _future;
- @override
- void initState() {
- super.initState();
- _controller = TabController(length: 3, vsync: this);
- _future = _getNotice();
- }
- Future<List<Notice>> _getNotice() async {
- List<Notice> 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 <Widget>[
- buildSliverAppBar(context, "社区消息", innerBoxIsScrolled: innerBoxIsScrolled),
- SliverPersistentHeader(
- delegate: PersistentHeader(
- min: tabHeader,
- max: tabHeader,
- child: Container(
- color: Colors.white,
- child: Column(
- children: <Widget>[
- 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: <Widget>[
- Tab(
- text: '聊天',
- ),
- Tab(
- child: Stack(
- clipBehavior: Clip.none,
- children: [
- Center(
- child: Text("消息"),
- ),
- ValueListenableBuilder(
- valueListenable: GetIt.I<MessageModel>().notifierSocial,
- builder: (BuildContext context, int value, Widget? child) {
- int v = value - GetIt.I<MessageModel>().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<String>('Tab1'), child: MessageListSubPage()),
- ListView.separated(
- key: const PageStorageKey<String>('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<MessageModel>().getCount();
- },
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 12.0),
- child: Row(children: <Widget>[
- 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<MessageModel>().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<MessageModel>().getCount();
- },
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 12.0),
- child: Row(children: <Widget>[
- 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<MessageModel>().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<String>('Tab3'),
- child: FutureBuilder(
- future: _future,
- builder: (_, AsyncSnapshot<List<Notice>> 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: <Widget>[
- 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: <Widget>[
- 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,
- );
- },
- ),
- )
- ])),
- );
- }
- }
|