Flutter Toogle最受欢迎的onDismissable活动,与Bloc一起颤振

Flutter Toogle最受欢迎的onDismissable活动,与Bloc一起颤振,flutter,dart,bloc,Flutter,Dart,Bloc,我在完成有关如何从列表中添加/删除(切换)收藏夹(来自api响应)的操作时遇到一些问题。实际上,我可以将收藏夹添加到列表中,也可以以单独的方式将其删除,但我不能以切换方式使用相同的按钮。简而言之,它正在工作,但我无法正确实现切换操作。请看一下代码,看看是否有一个很好的方法可以在不使用setstate的情况下实现切换 关闭按钮(从列表中删除) 同一个按钮实现通过Bloc向列表添加收藏夹 CupertinoButton( padding: EdgeIn

我在完成有关如何从列表中添加/删除(切换)收藏夹(来自api响应)的操作时遇到一些问题。实际上,我可以将收藏夹添加到列表中,也可以以单独的方式将其删除,但我不能以切换方式使用相同的按钮。简而言之,它正在工作,但我无法正确实现切换操作。请看一下代码,看看是否有一个很好的方法可以在不使用setstate的情况下实现切换

关闭按钮(从列表中删除)

同一个按钮实现通过Bloc向列表添加收藏夹

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,
                        ),
                      ),