如何在 flutter 评分栏中保存用户评分?
How to save User rating in flutter rating bar?
我正在尝试保存用户评分,以便在用户返回页面时显示它。但我有点挣扎,不知道该怎么做。评级有效,但正如我所说,储蓄无效。
所以发生的事情是它总是空的。我真正想要的是,如果用户返回页面,他会看到他的评分,如果他再次评分并且评分不同,我让他评分的最后一个评分,如果没有,则不,如果他按清除,评分将被删除也很好用。
也许任何人都可以提供帮助。
lass Ratingpage extends StatefulWidget {
final int maximumRating;
final Function(int) onRatingSelected;
Ratingpage(this.onRatingSelected, [this.maximumRating = 5]);
@override
_RatingpageState createState() => _RatingpageState();
}
class _RatingpageState extends State<Ratingpage> {
int haveusercurrentchoice;
int _currentRating = 0;
Widget _buildRatingStar(int index) {
if (index < _currentRating) {
return Icon(
Icons.star,
color: Colors.yellow,
);
} else {
return Icon(
Icons.star,
color: Colors.white,
);
}
}
Widget _buildBody() {
final stars = List<Widget>.generate(this.widget.maximumRating, (index) {
return Expanded(
child: GestureDetector(
child: _buildRatingStar(index),
onTap: () {
setState(() {
_currentRating = index;
});
this.widget.onRatingSelected(_currentRating);
},
),
);
});
return Row(
children: [
Expanded(
child: Row(
children: stars,
),
),
Expanded(
child: TextButton(
onPressed: () {
setState(() {
_currentRating = 0;
});
this.widget.onRatingSelected(_currentRating);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white),
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return _buildBody();
}
如果您需要更多信息,请发表评论。
这就是我调用页面的方式
Container(
width: 210,
height: 94,
//color: Colors.blue.withOpacity(0.5),
child: Column(
children: [
InkWell(
onTap: () {
setState(() {
israting = true;
});
// if( _rating !=null && _rating >0){
// likevideo(videos.data()['id']);}
},
child: israting
? Container(
height: 50,
margin: EdgeInsets.fromLTRB(
0, 0, 5, 0),
child: Column(
children: [
Ratingpage((rating) {
setState(() {
_rating = rating;
});
if (_rating != null &&
_rating > 0) {
likevideo(
videos.data()['id'],
_rating);
print(delteuserchoicing);
} else if (_rating ==
null ||
_rating == 0) {
dislike(
videos.data()['id'],
_rating);
}
}),
],
),
)
: Icon(
Icons.star,
size: 37,
color: videos
.data()['likes']
.contains(uid)
? Colors.yellow
: Colors.white,
),
),
其实是在一列里面
所以您在页面之间存储状态时遇到问题,然后在应用重启时存储评分时遇到问题。 2个独立的东西。您可能只关心前者,但这里是您如何使用 GetX State management and GetStorage 进行本地数据库存储。同样的事情可以用任何其他状态管理解决方案来完成,即。 Provider、Riverpod、Bloc 等...
GetStorage 可与 SharedPreferences
互换,但我认为任何使用过两者的人都会同意 GetStorage
更易于使用。
为了清理我的示例,我删除了完成您所要求的内容所不需要的任何内容。根据应用其余部分的情况,您可能不需要恢复我删除的大部分或全部变量。
首先,让我们将逻辑和变量移动到 GetX class,以便可以从应用程序的任何位置访问它们。它还有助于清理您的 UI 代码。
class RatingController extends GetxController {
int currentRating = 0;
final box = GetStorage();
@override
void onInit() { // called whenever we initialize the controller
super.onInit();
currentRating = box.read('rating') ?? 0; // initializing current rating from storage or 0 if storage is null
}
void updateAndStoreRating(int rating) {
currentRating = rating;
box.write('rating', rating); // stores to local database
update(); // triggers a rebuild of the GetBuilder Widget
}
Widget buildRatingStar(int index) {
if (index < currentRating) {
return Icon(
Icons.star,
color: Colors.yellow,
);
} else {
return Icon(
Icons.star,
color: Colors.white,
);
}
}
}
我在此页面上添加了一个按钮只是为了演示目的。由于此演示包括路由,我使用 Getx 也是一种更容易进行路由的方法,但它与回答您的问题完全无关或没有必要。此页面现在也可以是无状态的。
class Ratingpage extends StatelessWidget {
static const id = 'rating_page'; // see GetMaterialApp for this usage
final controller = Get.find<RatingController>(); // finding the same instance of initialized controller
Widget _buildBody() {
final stars = List<Widget>.generate(5, (index) {
return GetBuilder<RatingController>( // rebuilds when update() is called from GetX class
builder: (controller) => Expanded(
child: GestureDetector(
child: controller.buildRatingStar(index),
onTap: () {
controller.updateAndStoreRating(index + 1); // +1 because index starts at 0 otherwise the star rating is offset by one
},
),
),
);
});
return Row(
children: [
Expanded(
child: Row(
children: stars,
),
),
Expanded(
child: TextButton(
onPressed: () {
controller.updateAndStoreRating(0);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white),
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildBody(),
ElevatedButton(
onPressed: () {
Get.to(() => OtherPage()); // equivalent of Navigator.push....
},
child: Text('Other Page'),
)
],
);
}
}
您的主要方法现在看起来像这样,因为我们需要初始化控制器和存储。
void main() async {
await GetStorage.init();
Get.put(RatingController());
runApp(MyApp());
}
再说一遍,只是为了方便路由,我们使用 GetMaterialApp
并在那里定义页面。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Material App',
home: Ratingpage(),
getPages: [ // only necessary for routing, not for storage or state management
GetPage(name: OtherPage.id, page: () => OtherPage()),
GetPage(name: Ratingpage.id, page: () => Ratingpage()),
],
);
}
}
编辑:添加 SharedPreferences
由于未维护的包与 GetStorage 路径提供程序依赖性冲突。
将 SharedPreferences prefs;
添加到您的 GetX class。
现在这是您的更新功能。
void updateAndStoreRating(int rating) {
currentRating = rating;
prefs.setInt('rating', rating); //SharedPreferences way
update(); // triggers a rebuild of the GetBuilder Widget
}
在 GetX 控制器中添加一个初始化函数 class。
Future<void> initSp() async {
prefs = await SharedPreferences.getInstance();
currentRating = prefs.getInt('rating') ?? 0;
}
现在你的 main 有点不一样了。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final controller = Get.put(RatingController());
await controller.initSp();
runApp(MyApp());
}
我正在尝试保存用户评分,以便在用户返回页面时显示它。但我有点挣扎,不知道该怎么做。评级有效,但正如我所说,储蓄无效。 所以发生的事情是它总是空的。我真正想要的是,如果用户返回页面,他会看到他的评分,如果他再次评分并且评分不同,我让他评分的最后一个评分,如果没有,则不,如果他按清除,评分将被删除也很好用。
也许任何人都可以提供帮助。
lass Ratingpage extends StatefulWidget {
final int maximumRating;
final Function(int) onRatingSelected;
Ratingpage(this.onRatingSelected, [this.maximumRating = 5]);
@override
_RatingpageState createState() => _RatingpageState();
}
class _RatingpageState extends State<Ratingpage> {
int haveusercurrentchoice;
int _currentRating = 0;
Widget _buildRatingStar(int index) {
if (index < _currentRating) {
return Icon(
Icons.star,
color: Colors.yellow,
);
} else {
return Icon(
Icons.star,
color: Colors.white,
);
}
}
Widget _buildBody() {
final stars = List<Widget>.generate(this.widget.maximumRating, (index) {
return Expanded(
child: GestureDetector(
child: _buildRatingStar(index),
onTap: () {
setState(() {
_currentRating = index;
});
this.widget.onRatingSelected(_currentRating);
},
),
);
});
return Row(
children: [
Expanded(
child: Row(
children: stars,
),
),
Expanded(
child: TextButton(
onPressed: () {
setState(() {
_currentRating = 0;
});
this.widget.onRatingSelected(_currentRating);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white),
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return _buildBody();
}
如果您需要更多信息,请发表评论。
这就是我调用页面的方式
Container(
width: 210,
height: 94,
//color: Colors.blue.withOpacity(0.5),
child: Column(
children: [
InkWell(
onTap: () {
setState(() {
israting = true;
});
// if( _rating !=null && _rating >0){
// likevideo(videos.data()['id']);}
},
child: israting
? Container(
height: 50,
margin: EdgeInsets.fromLTRB(
0, 0, 5, 0),
child: Column(
children: [
Ratingpage((rating) {
setState(() {
_rating = rating;
});
if (_rating != null &&
_rating > 0) {
likevideo(
videos.data()['id'],
_rating);
print(delteuserchoicing);
} else if (_rating ==
null ||
_rating == 0) {
dislike(
videos.data()['id'],
_rating);
}
}),
],
),
)
: Icon(
Icons.star,
size: 37,
color: videos
.data()['likes']
.contains(uid)
? Colors.yellow
: Colors.white,
),
),
其实是在一列里面
所以您在页面之间存储状态时遇到问题,然后在应用重启时存储评分时遇到问题。 2个独立的东西。您可能只关心前者,但这里是您如何使用 GetX State management and GetStorage 进行本地数据库存储。同样的事情可以用任何其他状态管理解决方案来完成,即。 Provider、Riverpod、Bloc 等...
GetStorage 可与 SharedPreferences
互换,但我认为任何使用过两者的人都会同意 GetStorage
更易于使用。
为了清理我的示例,我删除了完成您所要求的内容所不需要的任何内容。根据应用其余部分的情况,您可能不需要恢复我删除的大部分或全部变量。
首先,让我们将逻辑和变量移动到 GetX class,以便可以从应用程序的任何位置访问它们。它还有助于清理您的 UI 代码。
class RatingController extends GetxController {
int currentRating = 0;
final box = GetStorage();
@override
void onInit() { // called whenever we initialize the controller
super.onInit();
currentRating = box.read('rating') ?? 0; // initializing current rating from storage or 0 if storage is null
}
void updateAndStoreRating(int rating) {
currentRating = rating;
box.write('rating', rating); // stores to local database
update(); // triggers a rebuild of the GetBuilder Widget
}
Widget buildRatingStar(int index) {
if (index < currentRating) {
return Icon(
Icons.star,
color: Colors.yellow,
);
} else {
return Icon(
Icons.star,
color: Colors.white,
);
}
}
}
我在此页面上添加了一个按钮只是为了演示目的。由于此演示包括路由,我使用 Getx 也是一种更容易进行路由的方法,但它与回答您的问题完全无关或没有必要。此页面现在也可以是无状态的。
class Ratingpage extends StatelessWidget {
static const id = 'rating_page'; // see GetMaterialApp for this usage
final controller = Get.find<RatingController>(); // finding the same instance of initialized controller
Widget _buildBody() {
final stars = List<Widget>.generate(5, (index) {
return GetBuilder<RatingController>( // rebuilds when update() is called from GetX class
builder: (controller) => Expanded(
child: GestureDetector(
child: controller.buildRatingStar(index),
onTap: () {
controller.updateAndStoreRating(index + 1); // +1 because index starts at 0 otherwise the star rating is offset by one
},
),
),
);
});
return Row(
children: [
Expanded(
child: Row(
children: stars,
),
),
Expanded(
child: TextButton(
onPressed: () {
controller.updateAndStoreRating(0);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white),
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildBody(),
ElevatedButton(
onPressed: () {
Get.to(() => OtherPage()); // equivalent of Navigator.push....
},
child: Text('Other Page'),
)
],
);
}
}
您的主要方法现在看起来像这样,因为我们需要初始化控制器和存储。
void main() async {
await GetStorage.init();
Get.put(RatingController());
runApp(MyApp());
}
再说一遍,只是为了方便路由,我们使用 GetMaterialApp
并在那里定义页面。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Material App',
home: Ratingpage(),
getPages: [ // only necessary for routing, not for storage or state management
GetPage(name: OtherPage.id, page: () => OtherPage()),
GetPage(name: Ratingpage.id, page: () => Ratingpage()),
],
);
}
}
编辑:添加 SharedPreferences
由于未维护的包与 GetStorage 路径提供程序依赖性冲突。
将 SharedPreferences prefs;
添加到您的 GetX class。
现在这是您的更新功能。
void updateAndStoreRating(int rating) {
currentRating = rating;
prefs.setInt('rating', rating); //SharedPreferences way
update(); // triggers a rebuild of the GetBuilder Widget
}
在 GetX 控制器中添加一个初始化函数 class。
Future<void> initSp() async {
prefs = await SharedPreferences.getInstance();
currentRating = prefs.getInt('rating') ?? 0;
}
现在你的 main 有点不一样了。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final controller = Get.put(RatingController());
await controller.initSp();
runApp(MyApp());
}