- 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.
91 lines
2.4 KiB
Dart
91 lines
2.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
/// 自定义实现,替代已停维的 `smooth_star_rating` 包的 [SmoothStarRating]。
|
|
///
|
|
/// 保留原命名参数(`allowHalfRating`/`onRated`/`starCount`/`rating`/`size`/
|
|
/// `filledIconData`/`color`/`borderColor`/`spacing`),调用方仅改 import 即可。
|
|
class SmoothStarRating extends StatefulWidget {
|
|
final bool allowHalfRating;
|
|
final void Function(double)? onRated;
|
|
final int starCount;
|
|
final double rating;
|
|
final double size;
|
|
final IconData filledIconData;
|
|
final IconData? halfFilledIconData;
|
|
final IconData? defaultIconData;
|
|
final Color color;
|
|
final Color borderColor;
|
|
final double spacing;
|
|
|
|
const SmoothStarRating({
|
|
super.key,
|
|
this.allowHalfRating = false,
|
|
this.onRated,
|
|
this.starCount = 5,
|
|
this.rating = 0.0,
|
|
this.size = 24.0,
|
|
this.filledIconData = Icons.star,
|
|
this.halfFilledIconData,
|
|
this.defaultIconData,
|
|
this.color = Colors.orange,
|
|
this.borderColor = Colors.orange,
|
|
this.spacing = 0.0,
|
|
});
|
|
|
|
@override
|
|
State<SmoothStarRating> createState() => _SmoothStarRatingState();
|
|
}
|
|
|
|
class _SmoothStarRatingState extends State<SmoothStarRating> {
|
|
late double _rating;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_rating = widget.rating;
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(covariant SmoothStarRating oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
if (oldWidget.rating != widget.rating) {
|
|
_rating = widget.rating;
|
|
}
|
|
}
|
|
|
|
Widget _star(int index) {
|
|
IconData icon;
|
|
Color iconColor;
|
|
if (index < _rating.floor()) {
|
|
icon = widget.filledIconData;
|
|
iconColor = widget.color;
|
|
} else if (widget.allowHalfRating &&
|
|
index == _rating.floor() &&
|
|
(_rating - index) >= 0.5) {
|
|
icon = widget.halfFilledIconData ?? Icons.star_half;
|
|
iconColor = widget.color;
|
|
} else {
|
|
icon = widget.defaultIconData ?? Icons.star_border;
|
|
iconColor = widget.borderColor;
|
|
}
|
|
return GestureDetector(
|
|
onTap: () {
|
|
setState(() => _rating = (index + 1).toDouble());
|
|
widget.onRated?.call(_rating);
|
|
},
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: widget.spacing / 2),
|
|
child: Icon(icon, size: widget.size, color: iconColor),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: List<Widget>.generate(widget.starCount, _star),
|
|
);
|
|
}
|
|
}
|