我正在使用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,
color: Colors.white,
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,
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,
),
),
CupertinoButton(
padding: EdgeInsets.zero,
minSize: 30,
onPressed: () {
Share.share(
'https://www.youtube.com/watch?v=${item.videoId}',
subject: 'Mira este impresionante documental');
},
child: CircleContainer(
child: Icon(
Icons.share,
color: Colors.white,
),
size: 35,
),
),
],
),
),
],
),
),
),
),
);
}
@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),
],
)
],
);
}
}
答案 0 :(得分:0)
只有一种状态吗?
我知道状态不会更改为同名状态。
如果要使用当前结构(如代码)。
在状态更改之间,您需要一个状态,例如“ 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 */,
startTime: this.startTime,
endTime: this.endTime,
logStreamNamePrefix: this.device,
filterPattern: `{ ($.device="${this.device}") }`,
};
}
// 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 {
}