feat: Phase 2 — upgrade deps to null-safe, replace deprecated packages
- 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.
This commit is contained in:
90
lib/widgets/general/smooth_star_rating.dart
Normal file
90
lib/widgets/general/smooth_star_rating.dart
Normal file
@@ -0,0 +1,90 @@
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user