Flutter评分插件flutter_rating_bar的使用
Flutter评分插件flutter_rating_bar的使用
flutter_rating_bar
是一个简单且完全可定制的Flutter评分条插件,支持任意分数的评分。
主要特性
- 设置最小和最大评分
- 任何小部件都可以用作评分条/指示器项
- 同一评分条中可以使用不同的小部件
- 支持垂直布局
- 交互时发光
- 支持RTL模式
使用方法
使用Flutter Rating Bar
评分条可以通过三种方式使用:
第一种方式:使用 RatingBar.builder()
RatingBar.builder(
initialRating: 3,
minRating: 1,
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
print(rating);
},
)
第二种方式:使用 RatingBar()
RatingBar(
initialRating: 3,
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
ratingWidget: RatingWidget(
full: _image('assets/heart.png'),
half: _image('assets/heart_half.png'),
empty: _image('assets/heart_border.png'),
),
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
onRatingUpdate: (rating) {
print(rating);
},
)
心形图标可以在这里找到。
第三种方式:使用 RatingBar.builder()
带有索引
RatingBar.builder(
initialRating: 3,
itemCount: 5,
itemBuilder: (context, index) {
switch (index) {
case 0:
return Icon(
Icons.sentiment_very_dissatisfied,
color: Colors.red,
);
case 1:
return Icon(
Icons.sentiment_dissatisfied,
color: Colors.redAccent,
);
case 2:
return Icon(
Icons.sentiment_neutral,
color: Colors.amber,
);
case 3:
return Icon(
Icons.sentiment_satisfied,
color: Colors.lightGreen,
);
case 4:
return Icon(
Icons.sentiment_very_satisfied,
color: Colors.green,
);
}
},
onRatingUpdate: (rating) {
print(rating);
},
)
使用Flutter Rating Bar Indicator
RatingBarIndicator(
rating: 2.75,
itemBuilder: (context, index) => Icon(
Icons.star,
color: Colors.amber,
),
itemCount: 5,
itemSize: 50.0,
direction: Axis.vertical,
)
垂直模式
在垂直模式下,为了使指示器可滚动,只需使用physics
属性,详情请参阅示例。
完整示例Demo
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final TextEditingController _ratingController;
double _rating = 3.0;
double _userRating = 3.0;
int _ratingBarMode = 1;
double _initialRating = 2.0;
bool _isRTLMode = false;
bool _isVertical = false;
IconData? _selectedIcon;
@override
void initState() {
super.initState();
_ratingController = TextEditingController(text: '3.0');
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.amber,
appBarTheme: AppBarTheme(
titleTextStyle: Theme.of(context).textTheme.headline6?.copyWith(color: Colors.white),
),
),
home: Builder(
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Flutter Rating Bar'),
actions: [
IconButton(
icon: Icon(Icons.settings),
color: Colors.white,
onPressed: () async {
_selectedIcon = await showDialog<IconData>(
context: context,
builder: (context) => IconAlert(),
);
_ratingBarMode = 1;
setState(() {});
},
),
],
),
body: Directionality(
textDirection: _isRTLMode ? TextDirection.rtl : TextDirection.ltr,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(height: 40.0),
_heading('Rating Bar'),
_ratingBar(_ratingBarMode),
SizedBox(height: 20.0),
Text(
'Rating: $_rating',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 40.0),
_heading('Rating Indicator'),
RatingBarIndicator(
rating: _userRating,
itemBuilder: (context, index) => Icon(
_selectedIcon ?? Icons.star,
color: Colors.amber,
),
itemCount: 5,
itemSize: 50.0,
unratedColor: Colors.amber.withAlpha(50),
direction: _isVertical ? Axis.vertical : Axis.horizontal,
),
SizedBox(height: 20.0),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: TextFormField(
controller: _ratingController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter rating',
labelText: 'Enter rating',
suffixIcon: MaterialButton(
onPressed: () {
_userRating = double.parse(_ratingController.text ?? '0.0');
setState(() {});
},
child: Text('Rate'),
),
),
),
),
SizedBox(height: 40.0),
_heading('Scrollable Rating Indicator'),
RatingBarIndicator(
rating: 8.2,
itemCount: 20,
itemSize: 30.0,
physics: BouncingScrollPhysics(),
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
),
SizedBox(height: 20.0),
Text(
'Rating Bar Modes',
style: TextStyle(fontWeight: FontWeight.w300),
),
Row(
children: [
_radio(1),
_radio(2),
_radio(3),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Switch to Vertical Bar',
style: TextStyle(fontWeight: FontWeight.w300),
),
Switch(
value: _isVertical,
onChanged: (value) {
setState(() {
_isVertical = value;
});
},
activeColor: Colors.amber,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Switch to RTL Mode',
style: TextStyle(fontWeight: FontWeight.w300),
),
Switch(
value: _isRTLMode,
onChanged: (value) {
setState(() {
_isRTLMode = value;
});
},
activeColor: Colors.amber,
),
],
),
],
),
),
),
),
),
);
}
Widget _radio(int value) {
return Expanded(
child: RadioListTile<int>(
value: value,
groupValue: _ratingBarMode,
dense: true,
title: Text(
'Mode $value',
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12.0,
),
),
onChanged: (value) {
setState(() {
_ratingBarMode = value!;
});
},
),
);
}
Widget _ratingBar(int mode) {
switch (mode) {
case 1:
return RatingBar.builder(
initialRating: _initialRating,
minRating: 1,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
allowHalfRating: true,
unratedColor: Colors.amber.withAlpha(50),
itemCount: 5,
itemSize: 50.0,
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
itemBuilder: (context, _) => Icon(
_selectedIcon ?? Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
case 2:
return RatingBar(
initialRating: _initialRating,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
ratingWidget: RatingWidget(
full: _image('assets/heart.png'),
half: _image('assets/heart_half.png'),
empty: _image('assets/heart_border.png'),
),
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
case 3:
return RatingBar.builder(
initialRating: _initialRating,
direction: _isVertical ? Axis.vertical : Axis.horizontal,
itemCount: 5,
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
itemBuilder: (context, index) {
switch (index) {
case 0:
return Icon(
Icons.sentiment_very_dissatisfied,
color: Colors.red,
);
case 1:
return Icon(
Icons.sentiment_dissatisfied,
color: Colors.redAccent,
);
case 2:
return Icon(
Icons.sentiment_neutral,
color: Colors.amber,
);
case 3:
return Icon(
Icons.sentiment_satisfied,
color: Colors.lightGreen,
);
case 4:
return Icon(
Icons.sentiment_very_satisfied,
color: Colors.green,
);
default:
return Container();
}
},
onRatingUpdate: (rating) {
setState(() {
_rating = rating;
});
},
updateOnDrag: true,
);
default:
return Container();
}
}
Widget _image(String asset) {
return Image.asset(
asset,
height: 30.0,
width: 30.0,
color: Colors.amber,
);
}
Widget _heading(String text) => Column(
children: [
Text(
text,
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 24.0,
),
),
SizedBox(
height: 20.0,
),
],
);
}
class IconAlert extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(
'Select Icon',
style: TextStyle(
fontWeight: FontWeight.w300,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
titlePadding: EdgeInsets.all(12.0),
contentPadding: EdgeInsets.all(0),
content: Wrap(
children: [
_iconButton(context, Icons.home),
_iconButton(context, Icons.airplanemode_active),
_iconButton(context, Icons.euro_symbol),
_iconButton(context, Icons.beach_access),
_iconButton(context, Icons.attach_money),
_iconButton(context, Icons.music_note),
_iconButton(context, Icons.android),
_iconButton(context, Icons.toys),
_iconButton(context, Icons.language),
_iconButton(context, Icons.landscape),
_iconButton(context, Icons.ac_unit),
_iconButton(context, Icons.star),
],
),
);
}
Widget _iconButton(BuildContext context, IconData icon) => IconButton(
icon: Icon(icon),
onPressed: () => Navigator.pop(context, icon),
splashColor: Colors.amberAccent,
color: Colors.amber,
);
}
更多关于Flutter评分插件flutter_rating_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter评分插件flutter_rating_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_rating_bar
插件的详细代码示例。flutter_rating_bar
是一个流行的Flutter插件,用于在应用中显示和处理评分条。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加flutter_rating_bar
的依赖:
dependencies:
flutter:
sdk: flutter
flutter_rating_bar: ^4.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Dart文件中(例如main.dart
),导入flutter_rating_bar
:
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
3. 使用RatingBar
下面是一个完整的示例,展示如何在Flutter应用中使用RatingBar
:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Rating Bar Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: RatingBarScreen(),
);
}
}
class RatingBarScreen extends StatefulWidget {
@override
_RatingBarScreenState createState() => _RatingBarScreenState();
}
class _RatingBarScreenState extends State<RatingBarScreen> {
double _rating = 3.0;
void _submitRating(double rating) {
setState(() {
_rating = rating;
});
print("User rated: $rating");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Rating Bar Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Rate this app:',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
RatingBar.builder(
initialRating: _rating,
minRating: 1,
direction: Axis.horizontal,
allowHalfRatings: true,
itemCount: 5,
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.amber,
),
onRatingUpdate: (rating) => _submitRating(rating),
),
SizedBox(height: 20),
Text(
'Current Rating: $_rating',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
],
),
),
);
}
}
解释
- 依赖添加:在
pubspec.yaml
中添加flutter_rating_bar
依赖。 - 导入插件:在Dart文件中导入
flutter_rating_bar
。 - UI构建:
- 使用
Scaffold
和AppBar
来构建应用的基本结构。 - 使用
Column
来排列文本和评分条。 - 使用
RatingBar.builder
来构建评分条,并设置初始评分、最小评分、方向、是否允许半星评分、星星数量和星星图标。 - 使用
onRatingUpdate
回调来更新评分。
- 使用
这个示例展示了如何在Flutter应用中集成和使用flutter_rating_bar
插件,并实时更新和显示用户评分。希望这对你有所帮助!