我正在使用youtube api并放置一个“收藏夹”切换按钮,以根据状态填充和清空图标,并将其保存在名为“收藏夹”的新页面的ListView中。在新页面中,一切正常,因为我可以看到最喜欢的图标已填充,但在当前视图中并未实时刷新/更新。如果我切换到statefulWidget,则可以使用“ setstate”使其工作,但是如果我从“收藏夹”页面中清空图标,则更改不会反映出来。
我的方法一定有问题,因为我应该使用Bloc状态来同时更改这两个状态,但实际上卡在了这里。请您看看我的代码并给我一些想法或想法吗?
Bloc文件
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 MasterToggleInFavorites) {
yield* _toggleInFavorites(event);
} else if (event is MasterLogout) {
yield this.state.copyWith(history: [], currentTab: 0);
}
}
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> _removeFromHistory(MasterRemoveFromHistory event) async* {
final history = List<YoutubeVideo>.from(this.state.history);
history.removeAt(event.index);
yield this.state.copyWith(history: history);
}
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.isFavorite = true;
yield this.state.copyWith(favorites: favorites);
} else {
final favorites = List<YoutubeVideo>.from(this.state.favorites);
favorites.removeAt(index);
event.youtubeVideo.isFavorite = false;
yield this.state.copyWith(favorites: favorites);
}
}
}
集团状态
class MasterState extends Equatable {
final int currentTab;
final List<YoutubeVideo> history;
final List<YoutubeVideo> favorites;
MasterState(
{@required this.currentTab, @required this.history, this.favorites});
static MasterState initialState() =>
MasterState(currentTab: 0, history: [], favorites: []);
MasterState copyWith(
{int currentTab,
List<YoutubeVideo> history,
List<YoutubeVideo> favorites}) {
return MasterState(
currentTab: currentTab ?? this.currentTab,
history: history ?? this.history,
favorites: favorites ?? this.favorites);
}
@override
List<Object> get props => [currentTab, history, favorites];
}
BloC活动
import 'package:documentales_app/models/youtube_video.dart';
abstract class MasterEvents {}
class MasterSetTab extends MasterEvents {
final int tab;
MasterSetTab(this.tab);
}
class MasterAddToHistory extends MasterEvents {
final YoutubeVideo youtubeVideo;
MasterAddToHistory(this.youtubeVideo);
}
class MasterRemoveFromHistory extends MasterEvents {
final int index;
MasterRemoveFromHistory(this.index);
}
class MasterToggleInFavorites extends MasterEvents {
final YoutubeVideo youtubeVideo;
MasterToggleInFavorites(this.youtubeVideo);
}
class MasterLogout extends MasterEvents {}
“收藏夹”标签
class FavsTab extends StatefulWidget {
@override
_FavsTabState createState() => _FavsTabState();
}
class _FavsTabState extends State<FavsTab> {
@override
Widget build(BuildContext context) {
final bloc = BlocProvider.of<MasterBloc>(context);
return BlocBuilder<MasterBloc, MasterState>(
builder: (_, state) {
if (state.favorites.length == 0) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset('assets/icons/empty.svg',
width: 50, color: Colors.greenAccent),
SizedBox(
height: 5,
),
Text(
'No hay favoritos ..',
style: TextStyle(
color: Colors.greenAccent,
fontWeight: FontWeight.bold,
fontSize: 20),
)
],
),
);
}
return ListView.builder(
itemBuilder: (_, index) {
final YoutubeVideo item = state.favorites[index];
return YoutubeVideoItem(
item: item,
onDismissed: () {
bloc.add(MasterToggleInFavorites(item));
},
);
},
itemCount: state.favorites.length,
);
},
condition: (prevState, newState) =>
prevState.favorites.length != newState.favorites.length,
);
}
}
称为状态的首页标签
class HomeTab extends StatefulWidget {
@override
_HomeTabState createState() => _HomeTabState();
}
class _HomeTabState extends State<HomeTab> {
AccountApi _accountApi = AccountApi();
YoutubeApi _youtubeApi = YoutubeApi(apiKey: API_KEY);
List<dynamic> _users = [];
List<PlayList> _playlists = [];
List<YoutubeVideo> _newVideos = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_load();
}
_load() async {
final users = await _accountApi.getUsers(1);
final List<PlayList> playLists =
await _youtubeApi.getPlaylists('UCCMksip5JfLMW4AJGsjTYUA');
final List<YoutubeVideo> newVideos = await _youtubeApi
.getPlaylistVideos('PLFXLg_sVKmuujWVeOmrzsM1NnDFa8uoNk');
setState(() {
_users.addAll(users);
_playlists.addAll(playLists);
_newVideos.addAll(newVideos);
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return ListView(
children: [
_isLoading
? HomeTabShimmer()
: Column(
children: [
TopPlayLists(items: _playlists),
SizedBox(height: 10),
NewVideos(
items: _newVideos,
),
SizedBox(height: 5),
],
)
],
);
}
}
最后切换按钮
CupertinoButton(
padding: EdgeInsets.zero,
minSize: 30,
onPressed: () {
masterBloc.add(MasterToggleInFavorites(item));
},
child: CircleContainer(
child: Icon(
//Icons.playlist_add,
item.isFavorite
? Icons.favorite
: Icons.favorite_border,
color: Colors.white,
),
size: 35,
),
),