From c047aae099c1c71e2a7c1aeaa02fec29aa161d8f Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Thu, 31 Jan 2019 22:07:52 +0800 Subject: [PATCH] feat: notification icon badge --- lib/main.dart | 68 ++++++++++++++++++++------------- lib/providers/notification.dart | 66 ++++++++++++++++++++------------ lib/providers/settings.dart | 2 - lib/screens/notifications.dart | 3 +- 4 files changed, 85 insertions(+), 54 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 6c5355d..9c1906b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,6 +13,42 @@ class Home extends StatefulWidget { class _HomeState extends State { int active = 0; + Widget _buildNotificationIcon(BuildContext context) { + int count = NotificationProvider.of(context).count; + if (count == 0) { + return Icon(Icons.notifications); + } + + String text = count > 99 ? '99+' : count.toString(); + + // https://stackoverflow.com/a/54094844 + return Stack(children: [ + Icon(Icons.notifications), + Positioned( + right: 0, + child: new Container( + padding: EdgeInsets.all(1), + decoration: new BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(6), + ), + constraints: BoxConstraints( + minWidth: 12, + minHeight: 12, + ), + child: new Text( + '$text', + style: new TextStyle( + color: Colors.white, + fontSize: 8, + ), + textAlign: TextAlign.center, + ), + ), + ) + ]); + } + List _buildNavigationItems() { return [ BottomNavigationBarItem( @@ -24,26 +60,7 @@ class _HomeState extends State { title: Text('Search'), ), BottomNavigationBarItem( - icon: StreamBuilder(builder: (context, snapshot) { - int count = snapshot.data; - // print(count); - - // https://stackoverflow.com/a/45434404 - if (count != null && count > 0) { - return Stack(children: [ - Icon(Icons.notifications), - Positioned( - // draw a red marble - top: 0, - right: 0, - child: Icon(Icons.brightness_1, - size: 8.0, color: Colors.redAccent), - ) - ]); - } else { - return Icon(Icons.notifications); - } - }), + icon: _buildNotificationIcon(context), title: Text('Notification'), ), BottomNavigationBarItem( @@ -75,6 +92,7 @@ class _HomeState extends State { data: CupertinoThemeData( // brightness: Brightness.dark, // barBackgroundColor: Color.fromRGBO(0x24, 0x29, 0x2e, 1), + // primaryColor: Color(0xff24292e), ), child: CupertinoTabScaffold( tabBar: CupertinoTabBar(items: _buildNavigationItems()), @@ -109,20 +127,19 @@ class _HomeState extends State { class App extends StatelessWidget { final isIos = Platform.isIOS; - final NotificationBloc notificationBloc; final SearchBloc searchBloc; - App(this.notificationBloc, this.searchBloc); + App(this.searchBloc); @override build(context) { return SearchProvider( bloc: searchBloc, child: NotificationProvider( - bloc: notificationBloc, child: SettingsProvider( child: DefaultTextStyle( - style: TextStyle(color: Color(0xff24292e)), + // style: TextStyle(color: Color(0xff24292e)), + style: TextStyle(color: Colors.black), child: Home(), // theme: ThemeData( // textTheme: TextTheme( @@ -137,7 +154,6 @@ class App extends StatelessWidget { } void main() async { - NotificationBloc notificationBloc = NotificationBloc(); SearchBloc searchBloc = SearchBloc(); // DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); @@ -147,5 +163,5 @@ void main() async { // IosDeviceInfo iosInfo = await deviceInfo.iosInfo; // print('Running on ${iosInfo.utsname.machine}'); // e.g. "iPod7,1" - runApp(App(notificationBloc, searchBloc)); + runApp(App(searchBloc)); } diff --git a/lib/providers/notification.dart b/lib/providers/notification.dart index cee7823..bd16250 100644 --- a/lib/providers/notification.dart +++ b/lib/providers/notification.dart @@ -1,37 +1,53 @@ -import 'dart:async'; -import 'package:flutter/widgets.dart'; -import 'package:rxdart/subjects.dart'; -import 'package:rxdart/rxdart.dart'; +import 'dart:io'; +import 'package:flutter/material.dart'; -class NotificationBloc { - final _count = BehaviorSubject(seedValue: 0); - final _updater = StreamController(); +class NotificationProvider extends StatefulWidget { + final Widget child; - Stream get count => _count.stream; - Sink get countUpdate => _updater.sink; + NotificationProvider({@required this.child}); - NotificationBloc() { - _updater.stream.listen((_) { - _count.add(99); + static _NotificationProviderState of(BuildContext context) { + return (context.inheritFromWidgetOfExactType(_InheritedNotificationProvider) + as _InheritedNotificationProvider) + .data; + } + + @override + _NotificationProviderState createState() => new _NotificationProviderState(); +} + +class _NotificationProviderState extends State { + int count = 0; + + @override + void initState() { + super.initState(); + } + + void setCount(int value) { + setState(() { + count = value; }); } + + @override + Widget build(BuildContext context) { + return new _InheritedNotificationProvider( + data: this, + child: widget.child, + ); + } } -class NotificationProvider extends InheritedWidget { - final NotificationBloc bloc; +class _InheritedNotificationProvider extends InheritedWidget { + final _NotificationProviderState data; - NotificationProvider({ + _InheritedNotificationProvider({ Key key, - Widget child, - @required NotificationBloc bloc, - }) : bloc = bloc, - super(key: key, child: child); + @required this.data, + @required Widget child, + }) : super(key: key, child: child); @override - bool updateShouldNotify(InheritedWidget oldWidget) => true; - - static NotificationBloc of(BuildContext context) => - (context.inheritFromWidgetOfExactType(NotificationProvider) - as NotificationProvider) - .bloc; + bool updateShouldNotify(_InheritedNotificationProvider old) => true; } diff --git a/lib/providers/settings.dart b/lib/providers/settings.dart index 4961a8c..02d134e 100644 --- a/lib/providers/settings.dart +++ b/lib/providers/settings.dart @@ -6,8 +6,6 @@ class LayoutMap { static const cupertino = 1; } -class SettingsState {} - class SettingsProvider extends StatefulWidget { final Widget child; diff --git a/lib/screens/notifications.dart b/lib/screens/notifications.dart index 287bb5f..52e6a7a 100644 --- a/lib/screens/notifications.dart +++ b/lib/screens/notifications.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' hide Notification; import 'package:flutter/cupertino.dart' hide Notification; import '../providers/settings.dart'; +import '../providers/notification.dart'; import '../screens/screens.dart'; import '../widgets/notification_item.dart'; import '../widgets/loading.dart'; @@ -66,7 +67,7 @@ class NotificationScreenState extends State { .listNotifications(all: index == 2, participating: index == 1) .toList(); - // NotificationProvider.of(context).countUpdate.add(ns.length); + NotificationProvider.of(context).setCount(ns.length); Map groupMap = {}; ns.forEach((item) {