Flutter Toogle最受欢迎的onDismissable活动,与Bloc一起颤振
我在完成有关如何从列表中添加/删除(切换)收藏夹(来自api响应)的操作时遇到一些问题。实际上,我可以将收藏夹添加到列表中,也可以以单独的方式将其删除,但我不能以切换方式使用相同的按钮。简而言之,它正在工作,但我无法正确实现切换操作。请看一下代码,看看是否有一个很好的方法可以在不使用setstate的情况下实现切换 关闭按钮(从列表中删除) 同一个按钮实现通过Bloc向列表添加收藏夹Flutter Toogle最受欢迎的onDismissable活动,与Bloc一起颤振,flutter,dart,bloc,Flutter,Dart,Bloc,我在完成有关如何从列表中添加/删除(切换)收藏夹(来自api响应)的操作时遇到一些问题。实际上,我可以将收藏夹添加到列表中,也可以以单独的方式将其删除,但我不能以切换方式使用相同的按钮。简而言之,它正在工作,但我无法正确实现切换操作。请看一下代码,看看是否有一个很好的方法可以在不使用setstate的情况下实现切换 关闭按钮(从列表中删除) 同一个按钮实现通过Bloc向列表添加收藏夹 CupertinoButton( padding: EdgeIn
CupertinoButton(
padding: EdgeInsets.zero,
minSize: 30,
onPressed: () {
masterBloc.add(MasterAddToFavorites(item));
},
child: CircleContainer(
child: Icon(
item.isFavorite
? Icons.favorite
: Icons.favorite_border,
color: Colors.white,
),
size: 35,
),
),
项目定义
class YoutbeVideo {
final String videoId, title, description, banner;
bool isFavorite;
YoutbeVideo(
{@required this.videoId,
@required this.title,
@required this.description,
@required this.banner,
this.isFavorite});
void toggleFavoriteStatus() {
isFavorite = !isFavorite;
}
分为3个文件的集团代码
大师集团
import 'package:bloc/bloc.dart';
import 'package:documentales_app/models/youtube_video.dart';
import 'master_events.dart';
import 'master_state.dart';
class MasterBloc extends Bloc<MasterEvents, MasterState> {
@override
MasterState get initialState => MasterState.initialState();
@override
Stream<MasterState> mapEventToState(MasterEvents event) async* {
if (event is MasterSetTab) {
yield this.state.copyWith(currentTab: event.tab);
} else if (event is MasterAddToHistory) {
yield* _addToHistory(event);
} else if (event is MasterRemoveFromHistory) {
yield* _removeFromHistory(event);
} else if (event is MasterRemoveFromFavorites) {
yield* _removeFromFavorites(event);
} else if (event is MasterLogout) {
yield this.state.copyWith(history: [], currentTab: 0);
} else if (event is MasterAddToFavorites) {
yield* _addToFavorites(event);
}
}
Stream<MasterState> _addToHistory(MasterAddToHistory event) async* {
final int index = this
.state
.history
.indexWhere((item) => item.videoId == event.youtubeVideo.videoId);
if (index == -1) {
final history = List<YoutubeVideo>.from(this.state.history);
history.add(event.youtubeVideo);
yield this.state.copyWith(history: history);
}
}
Stream<MasterState> _addToFavorites(MasterAddToFavorites event) async* {
final int index = this
.state
.favorites
.indexWhere((item) => item.videoId == event.youtubeVideo.videoId);
if (index == -1) {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.add(event.youtubeVideo);
yield this.state.copyWith(favorites: favorites);
}
}
Stream<MasterState> _removeFromHistory(MasterRemoveFromHistory event) async* {
final history = List<YoutubeVideo>.from(this.state.history);
history.removeAt(event.index);
yield this.state.copyWith(history: history);
}
Stream<MasterState> _removeFromFavorites(
MasterRemoveFromFavorites event) async* {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.removeAt(event.index);
yield this.state.copyWith(favorites: favorites);
}
}
所以执行切换的一种方法是用一个事件替换添加和删除事件。所以你可以摆脱这些事件:
class MasterAddToFavorites extends MasterEvents {
final YoutubeVideo youtubeVideo;
MasterAddToFavorites(this.youtubeVideo);
}
class MasterRemoveFromFavorites extends MasterEvents {
final int index;
MasterRemoveFromFavorites(this.index);
}
并将其替换为:
class MasterToggleInFavorites extends MasterEvents {
final YoutubeVideo video;
MasterToggleInFavorites(video);
}
接下来,在bloc内部,在处理该事件的方法内部,您可以执行如下操作:
Stream<MasterState> _toggleInFavorites(MasterToggleInFavorites event) async* {
final int index = this
.state
.favorites
.indexWhere((item) => item.videoId == event.youtubeVideo.videoId);
if (index == -1) {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.add(event.youtubeVideo);
event.youtubeVideo.isFavourite = true;
yield this.state.copyWith(favorites: favorites);
} else {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.removeAt(index);
event.youtubeVideo.isFavourite = false;
yield this.state.copyWith(favorites: favorites);
}
Stream\u toggleInFavorites(MasterToggleInFavorites事件)异步*{
最终int索引=此
.州
.最爱
.indexWhere((项)=>item.videoId==event.youtubeVideo.videoId);
如果(索引==-1){
最终收藏夹=List.from(this.state.favorites);
收藏夹。添加(event.youtubeVideo);
event.youtubeVideo.isfavorite=true;
生成此.state.copyWith(收藏夹:收藏夹);
}否则{
最终收藏夹=List.from(this.state.favorites);
收藏夹.removeAt(索引);
event.youtubeVideo.isfavorite=false;
生成此.state.copyWith(收藏夹:收藏夹);
}
视频课程
class YoutubeVideo {
final String videoId, title, description, banner;
bool isFavorite;
YoutubeVideo(
{@required this.videoId,
@required this.title,
@required this.description,
@required this.banner,
this.isFavorite = false});
factory YoutubeVideo.fromJson(Map<String, dynamic> json,
{bool fromPlayList = false}) {
final snippet = json['snippet'];
final thumbnail =
snippet['thumbnails']['standard'] ?? snippet['thumbnails']['high'];
String videoId;
if (!fromPlayList) {
videoId = json['contentDetails']['videoId'];
} else {
videoId = snippet['resourceId']['videoId'];
}
return YoutubeVideo(
videoId: videoId,
title: snippet['title'],
description: snippet['description'],
banner: thumbnail['url']);
}
}
你也可以在bloc中共享代码吗?在bloc文件中添加了代码,谢谢!如果不是添加和删除两个单独的状态,而是有一个和该状态的bloc将签入列表,如果对象已经存在,如果存在,则将其从列表中删除,如果没有,则将其添加到列表中。是的,我一直在考虑,但我没有找不到方法。它工作得很好。但是仍然无法根据切换的变化反映图标中的变化来显示颜色。尝试创建一些包装类,其中包含两个字段:视频和bool,如果它是最喜欢的或不喜欢的。我已经添加了上面的类和按钮,以防你看到代码。出于任何原因儿子,我错过了一些东西,因为它没有反映颜色的变化。我是新来的,所以如果这是一个noob问题,请容忍我。是的,我知道,这是我无法实现的。它可能看起来很简单,但我对它感到疯狂,因为我尝试了许多不同的方法,并在它上结巴。非常感谢!我更新了我的帖子,看看!InFavorites方法您只需在按下按钮时在YouTube设备上设置
isFavorite
bool即可。
class MasterToggleInFavorites extends MasterEvents {
final YoutubeVideo video;
MasterToggleInFavorites(video);
}
Stream<MasterState> _toggleInFavorites(MasterToggleInFavorites event) async* {
final int index = this
.state
.favorites
.indexWhere((item) => item.videoId == event.youtubeVideo.videoId);
if (index == -1) {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.add(event.youtubeVideo);
event.youtubeVideo.isFavourite = true;
yield this.state.copyWith(favorites: favorites);
} else {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.removeAt(index);
event.youtubeVideo.isFavourite = false;
yield this.state.copyWith(favorites: favorites);
}
class YoutubeVideo {
final String videoId, title, description, banner;
bool isFavorite;
YoutubeVideo(
{@required this.videoId,
@required this.title,
@required this.description,
@required this.banner,
this.isFavorite = false});
factory YoutubeVideo.fromJson(Map<String, dynamic> json,
{bool fromPlayList = false}) {
final snippet = json['snippet'];
final thumbnail =
snippet['thumbnails']['standard'] ?? snippet['thumbnails']['high'];
String videoId;
if (!fromPlayList) {
videoId = json['contentDetails']['videoId'];
} else {
videoId = snippet['resourceId']['videoId'];
}
return YoutubeVideo(
videoId: videoId,
title: snippet['title'],
description: snippet['description'],
banner: thumbnail['url']);
}
}
CupertinoButton(
padding: EdgeInsets.zero,
minSize: 30,
onPressed: () {
masterBloc.add(MasterToggleInFavorites(item));
},
child: CircleContainer(
child: Icon(
//Icons.playlist_add,
item.isFavorite
? Icons.favorite_border
: Icons.favorite,
color: Colors.white,
),
size: 35,
),
),