以下Flutter代码适用于永久可在后台运行的秒表。当我仅使用一个提供程序时,效果很好:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(
TimerServiceProvider(
service: TimerService(),
child: MyApp(),
),
);
}
class TimerService extends ChangeNotifier {
Stopwatch _watch;
Timer _timer;
Duration get currentDuration => _currentDuration;
Duration _currentDuration = Duration.zero;
bool get isRunning => _timer != null;
TimerService() {
_watch = Stopwatch();
}
void _onTick(Timer timer) {
_currentDuration = _watch.elapsed;
// notify all listening widgets
notifyListeners();
}
void start() {
if (_timer != null) return;
_timer = Timer.periodic(Duration(seconds: 1), _onTick);
_watch.start();
notifyListeners();
}
void stop() {
_timer?.cancel();
_timer = null;
_watch.stop();
_currentDuration = _watch.elapsed;
notifyListeners();
}
void reset() {
stop();
_watch.reset();
_currentDuration = Duration.zero;
notifyListeners();
}
static TimerService of(BuildContext context) {
var provider =
context.dependOnInheritedWidgetOfExactType<TimerServiceProvider>();
return provider.service;
}
}
class TimerServiceProvider extends InheritedWidget {
const TimerServiceProvider({Key key, this.service, Widget child})
: super(key: key, child: child);
final TimerService service;
@override
bool updateShouldNotify(TimerServiceProvider old) => service != old.service;
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Service Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var timerService = TimerService.of(context);
return Scaffold(
appBar: AppBar(),
body: Center(
child: AnimatedBuilder(
animation: timerService, // listen to ChangeNotifier
builder: (context, child) {
// this part is rebuilt whenever notifyListeners() is called
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Elapsed: ${timerService.currentDuration}'),
RaisedButton(
onPressed: !timerService.isRunning
? timerService.start
: timerService.stop,
child: Text(!timerService.isRunning ? 'Start' : 'Stop'),
),
RaisedButton(
onPressed: timerService.reset,
child: Text('Reset'),
)
],
);
},
),
),
);
}
}
但是,我需要在我的应用程序中使用多个提供程序,当我将此提供程序包装在MultiProvider中时,出现一个错误,指出该错误:无法将元素类型“ TimerServiceProvider”分配给列表类型“ SingleChildWidget” '。 (list_element_type_not_assignable
我用于将提供程序包装在MultiProvider中的代码如下:
void main() {
runApp(
MultiProvider(
providers: [
TimerServiceProvider(service: TimerService(),
),
],
child: MyApp(),)
);
}
有人知道我在做什么吗?
答案 0 :(得分:0)
您可以在下面复制粘贴运行完整代码
您可以使用ChangeNotifierProvider
和Provider.of<TimerService>
代码段
void main() {
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => TimerService()),
],
child: MyApp(),
));
}
...
@override
Widget build(BuildContext context) {
var timerService = Provider.of<TimerService>(context, listen: false);
工作演示
完整代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => TimerService()),
],
child: MyApp(),
));
}
class TimerService extends ChangeNotifier {
Stopwatch _watch;
Timer _timer;
Duration get currentDuration => _currentDuration;
Duration _currentDuration = Duration.zero;
bool get isRunning => _timer != null;
TimerService() {
_watch = Stopwatch();
}
void _onTick(Timer timer) {
_currentDuration = _watch.elapsed;
// notify all listening widgets
notifyListeners();
}
void start() {
if (_timer != null) return;
_timer = Timer.periodic(Duration(seconds: 1), _onTick);
_watch.start();
notifyListeners();
}
void stop() {
_timer?.cancel();
_timer = null;
_watch.stop();
_currentDuration = _watch.elapsed;
notifyListeners();
}
void reset() {
stop();
_watch.reset();
_currentDuration = Duration.zero;
notifyListeners();
}
/*static TimerService of(BuildContext context) {
var provider =
context.dependOnInheritedWidgetOfExactType<TimerServiceProvider>();
return provider.service;
}*/
}
class TimerServiceProvider extends InheritedWidget {
const TimerServiceProvider({Key key, this.service, Widget child})
: super(key: key, child: child);
final TimerService service;
@override
bool updateShouldNotify(TimerServiceProvider old) => service != old.service;
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Service Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var timerService = Provider.of<TimerService>(context, listen: false);
return Scaffold(
appBar: AppBar(),
body: Center(
child: AnimatedBuilder(
animation: timerService, // listen to ChangeNotifier
builder: (context, child) {
// this part is rebuilt whenever notifyListeners() is called
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Elapsed: ${timerService.currentDuration}'),
RaisedButton(
onPressed: !timerService.isRunning
? timerService.start
: timerService.stop,
child: Text(!timerService.isRunning ? 'Start' : 'Stop'),
),
RaisedButton(
onPressed: timerService.reset,
child: Text('Reset'),
)
],
);
},
),
),
);
}
}