问题描述
我正在使用Bloc软件包来更新Flutter应用上的窗口小部件。我尝试更新一个变量,它是收藏夹列表。为此,我要获取状态并将其修改为新值,然后产生新的one(state)。结果是无法在当前页面中看到反映的更改,但正在克隆状态下工作(因为它已正确加载到新选项卡中)。我做错了什么,因为我看不到当前状态中反映的更改,但能够在克隆中完成更改?如果有不清楚的地方,请告诉我,否则我应该从我的代码库中分享其他内容。
更新1:如果我手动进行热重装,我可以看到更改,但是我想自动完成。
主州
import 'package:Meta/Meta.dart' show required;
import 'package:documentales_app/models/youtube_video.dart';
import 'package:equatable/equatable.dart';
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
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);
}
}
切换按钮
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,
“收藏夹”标签
import 'package:cached_network_image/cached_network_image.dart';
import 'package:documentales_app/blocs/pages/master_bloc/master_bloc.dart';
import 'package:documentales_app/blocs/pages/master_bloc/master_events.dart';
import 'package:documentales_app/models/youtube_video.dart';
import 'package:share/share.dart';
import 'package:documentales_app/widgets/circle_container.dart';
import 'package:Flutter_bloc/Flutter_bloc.dart';
import 'package:Flutter_youtube/Flutter_youtube.dart';
import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import '../utils/keys.dart';
class YoutubeVideoItem extends StatelessWidget {
final VoidCallback ondismissed;
final YoutubeVideo item;
const YoutubeVideoItem({@required this.item,this.ondismissed})
: assert(item != null);
Widget _getView(MasterBloc masterBloc) {
return Container(
child: CupertinoButton(
padding: EdgeInsets.zero,onpressed: () {
masterBloc.add(MasteraddToHistory(item));
FlutterYoutube.playYoutubeVideoByUrl(
apiKey: API_KEY,videoUrl: "https://www.youtube.com/watch?v=${item.videoId}",autoplay: true,//default falase
fullScreen: true //default false
);
},child: AspectRatio(
aspectRatio: 12 / 3,child: Container(
margin: EdgeInsets.symmetric(vertical: 5,horizontal: 10),padding: EdgeInsets.all(5),decoration: Boxdecoration(
borderRadius: BorderRadius.circular(10),color: Colors.greenAccent,BoxShadow: [
BoxShadow(color: Colors.black26,blurRadius: 5),],child: Row(
children: [
Expanded(
flex: 4,child: ClipRRect(
borderRadius: BorderRadius.circular(10),child: CachednetworkImage(
imageUrl: item.banner,fit: BoxFit.cover,height: double.infinity,Expanded(
flex: 5,child: Container(
padding: EdgeInsets.all(10),child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
Text(
item.title,maxLines: 2,style: TextStyle(
fontWeight: FontWeight.w500,fontSize: 14),SizedBox(
height: 5,Expanded(
child: Text(
item.description,overflow: TextOverflow.fade,style: TextStyle(
fontWeight: FontWeight.w300,color: Colors.grey[600],fontSize: 13),Expanded(
flex: 1,child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: [
CupertinoButton(
padding: EdgeInsets.zero,CupertinoButton(
padding: EdgeInsets.zero,onpressed: () {
Share.share(
'https://www.youtube.com/watch?v=${item.videoId}',subject: 'Mira este impresionante documental');
},child: CircleContainer(
child: Icon(
Icons.share,);
}
@override
Widget build(BuildContext context) {
final masterBloc = BlocProvider.of<MasterBloc>(context);
if (ondismissed != null) {
return dismissible(
key: Key(item.videoId),ondismissed: (_) {
if (ondismissed != null) {
ondismissed();
}
},child: _getView(masterBloc),);
}
return _getView(masterBloc);
}
}
主页标签
import 'package:cached_network_image/cached_network_image.dart';
import 'package:documentales_app/api/account_api.dart';
import 'package:documentales_app/api/youtube_api.dart';
import 'package:documentales_app/models/play_list.dart';
import 'package:documentales_app/models/youtube_video.dart';
import 'package:documentales_app/pages/home_page_widgets/home_tab_shimmer.dart';
import 'package:documentales_app/pages/home_page_widgets/new_videos.dart';
import 'package:documentales_app/pages/home_page_widgets/top_play_lists.dart';
import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import '../../utils/keys.dart';
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('jklnvfyyklhjh');
final List<YoutubeVideo> newVideos = await _youtubeApi
.getPlaylistVideos('PLFXLg_sbbjkGKJbkjgkkGKkgk');
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),)
],);
}
}
解决方法
只有一种状态吗?
我知道状态不会更改为同名状态。
如果要使用当前结构(如代码)。
在状态更改之间,您需要一个状态,例如“ MasterStateChanging”。
loadCloudWatchLogs(nextToken?: string) {
// Set the region
AWS.config.update({
region: 'sa-east-1',credentials: {
accessKeyId: environment.awsAccessKeyId,secretAccessKey: environment.awsSecretAccessKey,},});
// Create the CloudWatchLogs service object
const cloudwatchlogs = new AWS.CloudWatchLogs({ apiVersion: '2014-03-28' });
// Defines the params attributes pattern.
let params: AWSCloudWatchParams;
// Check if token was provided to permorm a next query to AWSCloudWatchLogs.
if (nextToken) {
params = {
logGroupName: 'group-name' /* required */,startTime: this.startTime,endTime: this.endTime,logStreamNamePrefix: this.device,filterPattern: `{ ($.device="${this.device}") }`,nextToken,};
} else {
params = {
logGroupName: 'group-name' /* required */,};
}
// Execute a filter for logs.
cloudwatchlogs.filterLogEvents(params,(err,data) => {
if (err) {
console.log(err,err.stack);
} else {
if (data.searchedLogStreams.length > 0) {
// Chegk if exists more logs for query.
const loadMoreLogs = !data.searchedLogStreams[
data.searchedLogStreams.length - 1
].searchedCompletely;
// Update the token for the next query.
this.nextToken = data.nextToken;
data.events.forEach(log => {
// log proccessing...
});
}
}
});
}
<State File>
class MasterStateChanging extends Equatable {
}