Flutter - настраиваемая панель рейтингов
Панель рейтинга, как следует из названия, используется для оценки контента внутри приложения. Более или менее все приложения используют их либо для получения отзывов пользователей о своем приложении, либо для получения рейтинга контента, размещенного в приложении. Такие приложения, как IMDB, используют их для оценки фильмов и сериалов, а приложения, подобные IMDB, используют их для получения отзывов о своих услугах от клиентов.
В этой статье мы создадим простое приложение со следующими функциями:
- Горизонтальная полоса рейтинга
- Переключатель, позволяющий перемещать все рейтинговые полосы вверху справа налево.
- Переключатель, позволяющий сделать шкалу рейтинга вертикальной.
- Три различных режима для изменения значка первой панели рейтинга
Чтобы создать указанное выше приложение, выполните следующие действия:
- Добавьте зависимость в файл pubspec.yaml
- Импортировать зависимость в файл main.dart
- Используйте StatefulWidget, чтобы структурировать приложение
- Добавьте вертикальную полосу рейтинга
- Добавьте переключатель, чтобы изменить выравнивание рейтинговых полос справа налево (RTL)
- Добавьте переключатель, чтобы изменить выравнивание шкалы рейтинга с горизонтального на вертикальное.
- Добавьте 3 разных режима, которые изменяют значки пользовательского интерфейса.
Добавление зависимости:
Чтобы добавить зависимость в файл pubspec.yaml, следуйте следующему изображению:
Импорт зависимости:
Чтобы импортировать зависимость flutter_rating_bar к файлу main.dart, используйте следующее:
import 'package: flutter_rating_bar / flutter_rating_bar.dart';
Структурирование приложения:
StatefulWidget можно использовать для предоставления приложению панели приложений и тела для хранения содержимого, как показано ниже:
Дротик
class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { var _ratingController = TextEditingController(); double _rating; int _ratingBarMode = 1; bool _isRTLMode = false ; bool _isVertical = false ; IconData _selectedIcon; @override void initState() { _ratingController.text = "3.0" ; super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false , theme: ThemeData( primarySwatch: Colors.green, appBarTheme: AppBarTheme( textTheme: TextTheme( title: Theme.of(context).textTheme.title.copyWith( color: Colors.white, ), ), ), ), |
Создание вертикальной шкалы оценок:
Простую панель рейтинга можно вызвать из пакета flutter_rating_bar , вызвав виджет RatingBar, как показано ниже:
Дротик
RatingBar( 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); }, ); |
Добавление переключателя RTL:
На этом этапе мы добавим переключатель, который может изменять выравнивание шкалы рейтинга слева направо, справа налево. Это можно сделать, используя MainAxisAlignment как MainAxisAlignment.center и вызывая режим _isRTL, как показано ниже:
Дротик
mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'Switch to RTL Mode' , style: TextStyle( fontWeight: FontWeight.w300, ), ), Switch( value: _isRTLMode, onChanged: (value) { setState(() { _isRTLMode = value; }); }, |
Добавление переключателя вертикального выравнивания:
На этом этапе мы добавим переключатель, который может изменять выравнивание шкалы рейтинга слева направо, справа налево. Это можно сделать, используя MainAxisAlignment как MainAxisAlignment.center и вызывая режим _isVertical, как показано ниже:
Дротик
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, ), ], ), |
Добавление режимов в панель рейтинга:
В этом приложении мы добавим 3 режима, и при выборе каждого режима значок шкалы рейтинга изменится. Мы будем использовать функцию switch (), чтобы назначить случаи режимам и назначить значки таким же образом, как показано ниже:
Дротик
Widget _ratingBar( int mode) { switch (mode) { case 1: return RatingBar( initialRating: 2, 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; }); }, ); case 2: return RatingBar( initialRating: 3, 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; }); }, ); case 3: return RatingBar( initialRating: 3, direction: _isVertical ? Axis.vertical : Axis.horizontal, itemCount: 5, itemPadding: EdgeInsets.symmetric(horizontal: 4.0), itemBuilder: (context, index) { switch (index) { case 0: Icon( return Icons.sentiment_very_dissatisfied, color: Colors.red, ); case 1: Icon( return Icons.sentiment_dissatisfied, color: Colors.redAccent, ); case 2: Icon( return Icons.sentiment_neutral, color: Colors.amber, ); case 3: Icon( return Icons.sentiment_satisfied, color: Colors.lightGreen, ); case 4: Icon( return Icons.sentiment_very_satisfied, color: Colors.green, ); default : return Container(); } }, onRatingUpdate: (rating) { setState(() { _rating = rating; }); }, ); default : return Container(); } } |
Полный исходный код:
Дротик
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> { var _ratingController = TextEditingController(); double _rating; int _ratingBarMode = 1; bool _isRTLMode = false ; bool _isVertical = false ; IconData _selectedIcon; @override void initState() { _ratingController.text = "3.0" ; super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false , theme: ThemeData( primarySwatch: Colors.green, appBarTheme: AppBarTheme( textTheme: TextTheme( title: Theme.of(context).textTheme.title.copyWith( color: Colors.white, ), ), ), ), home: Builder( builder: (context) => Scaffold( appBar: AppBar( title: Text( 'GeeksForGeeks' ), backgroundColor: Colors.green, ), 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, ), _rating != null ? Text( "Rating: $_rating" , style: TextStyle(fontWeight: FontWeight.bold), ) : Container(), 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( 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( initialRating: 2, 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; }); }, ); case 2: return RatingBar( initialRating: 3, 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; }); }, ); case 3: return RatingBar( initialRating: 3, direction: _isVertical ? Axis.vertical : Axis.horizontal, itemCount: 5, itemPadding: EdgeInsets.symmetric(horizontal: 4.0), itemBuilder: (context, index) { switch (index) { case 0: Icon( return Icons.sentiment_very_dissatisfied, color: Colors.red, ); case 1: Icon( return Icons.sentiment_dissatisfied, color: Colors.redAccent, ); case 2: Icon( return Icons.sentiment_neutral, color: Colors.amber, ); case 3: Icon( return Icons.sentiment_satisfied, color: Colors.lightGreen, ); case 4: Icon( return Icons.sentiment_very_satisfied, color: Colors.green, ); default : return Container(); } }, onRatingUpdate: (rating) { setState(() { _rating = rating; }); }, ); default : return Container(); } } РЕКОМЕНДУЕМЫЕ СТАТЬИ |