feat: notification icon badge

This commit is contained in:
Rongjian Zhang 2019-01-31 22:07:52 +08:00
parent 7d6557d02c
commit c047aae099
4 changed files with 85 additions and 54 deletions

View File

@ -13,6 +13,42 @@ class Home extends StatefulWidget {
class _HomeState extends State<Home> {
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: <Widget>[
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<BottomNavigationBarItem> _buildNavigationItems() {
return [
BottomNavigationBarItem(
@ -24,26 +60,7 @@ class _HomeState extends State<Home> {
title: Text('Search'),
),
BottomNavigationBarItem(
icon: StreamBuilder<int>(builder: (context, snapshot) {
int count = snapshot.data;
// print(count);
// https://stackoverflow.com/a/45434404
if (count != null && count > 0) {
return Stack(children: <Widget>[
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<Home> {
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<Home> {
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));
}

View File

@ -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<int> 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<NotificationProvider> {
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;
}

View File

@ -6,8 +6,6 @@ class LayoutMap {
static const cupertino = 1;
}
class SettingsState {}
class SettingsProvider extends StatefulWidget {
final Widget child;

View File

@ -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<NotificationScreen> {
.listNotifications(all: index == 2, participating: index == 1)
.toList();
// NotificationProvider.of(context).countUpdate.add(ns.length);
NotificationProvider.of(context).setCount(ns.length);
Map<String, NotificationGroup> groupMap = {};
ns.forEach((item) {