- pubspec: bump all maintained deps to null-safe latest; flutter pub get resolves
- Remove 12 packages (0-ref or no null-safe): splashscreen, flappy_search_bar,
searchable_dropdown, share, platform_detect, flutter_inappwebview, countdown,
gender_selection, flutter_dash, smooth_star_rating, hovering, ffi
- Add flutter_rating_bar
- Keep discontinued-but-null-safe for now (Phase 5): pull_to_refresh, hive, catcher
- New null-safe custom components (API-compatible, callers change only imports):
utils/countdown.dart, widgets/general/{hover_widget,gender_selection,
smooth_star_rating,search_bar}.dart
- main.dart: drop dead SplashScreen _buildBody + _to field
- 23 consuming files: swap deprecated imports to local components
Null-safety migration + upgraded-API adaptation = Phase 3.
30 lines
850 B
Dart
30 lines
850 B
Dart
import 'dart:async';
|
||
|
||
/// 自定义实现,替代已停维的 `countdown` 包的 [CountDown]。
|
||
///
|
||
/// 用法与原包兼容:
|
||
/// ```dart
|
||
/// var listener = CountDown(Duration(seconds: 90)).stream.listen(null);
|
||
/// listener.onData((Duration d) { ... d.inSeconds ... });
|
||
/// listener.onDone(() { ... });
|
||
/// ```
|
||
///
|
||
/// `stream` 每秒发出剩余 [Duration](从满时长倒数到 0),到达 0 后关闭。
|
||
class CountDown {
|
||
CountDown(this.duration) : assert(!duration.isNegative);
|
||
|
||
final Duration duration;
|
||
|
||
Stream<Duration> get stream => _countdownStream();
|
||
|
||
Stream<Duration> _countdownStream() async* {
|
||
int remaining = duration.inSeconds;
|
||
while (remaining > 0) {
|
||
yield Duration(seconds: remaining);
|
||
await Future<void>.delayed(const Duration(seconds: 1));
|
||
remaining--;
|
||
}
|
||
yield Duration.zero;
|
||
}
|
||
}
|