我最近开始陷入扑朔迷离的Bloc模式,并学会了使用此project。 在这个项目中,有一个新增的发布功能,因此我想实现一个相同的功能。 即使我通过事件更改了Bloc的状态,也没有将Container Widget添加到ListView。我尝试并搜索了此问题,但无法确定:(
这是我的下面的代码。
这里是集团零件,
@immutable
abstract class ContentsState extends Equatable {
ContentsState([List props = const []]) : super(props);
}
class ContentsLoading extends ContentsState {
@override
String toString() => 'ContentsLoading';
}
class ContentsLoaded extends ContentsState {
final List<Content> contents;
ContentsLoaded(this.contents);
@override
String toString() => 'ContentsLoaded { contents: $contents }';
}
@immutable
abstract class ContentsEvent extends Equatable {
ContentsEvent([List props = const []]) : super(props);
}
class LoadContents extends ContentsEvent {
@override
String toString() => 'LoadContents';
}
class AddContent extends ContentsEvent {
final Content content;
AddContent(this.content) : super([content]);
@override
String toString() => 'AddContent { content: $content }';
}
class ContentsBloc extends Bloc<ContentsEvent, ContentsState> {
@override
ContentsState get initialState => ContentsLoading();
@override
Stream<ContentsState> mapEventToState(ContentsEvent event) async* {
if (event is LoadContents) {
yield* _mapLoadContentsToState();
} else if (event is AddContent) {
yield* _mapAddContentToState(event);
}
}
Stream<ContentsState> _mapLoadContentsToState() async* {
final List<Content> contents = [Content('message')];
yield ContentsLoaded(contents);
}
Stream<ContentsState> _mapAddContentToState(AddContent event) async* {
if (currentState is ContentsLoaded) {
final List<Content> updateContents =
List.from((currentState as ContentsLoaded).contents)
..add(event.content);
// Output update contents
print('update contents : $updateContents');
yield ContentsLoaded(updateContents);
}
}
}
和演示部分
class AddPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
builder: (context) => ContentsBloc()..dispatch(LoadContents()),
child: Column(
children: <Widget>[
AddBody(),
InputArea(),
],
),
);
}
}
class AddBody extends StatelessWidget {
AddBody({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final contentsBloc = BlocProvider.of<ContentsBloc>(context);
return BlocBuilder(
bloc: contentsBloc,
builder: (
BuildContext context,
ContentsState state,
) {
if (state is ContentsLoading) {
return Center(child: CircularProgressIndicator());
} else if (state is ContentsLoaded) {
final contents = state.contents;
return Expanded(
child: ListView.builder(
itemCount: contents.length,
itemBuilder: (context, index) {
final content = contents[index];
return ContentItem(content: content);
},
),
);
}
},
);
}
}
class ContentItem extends StatelessWidget {
final Content content;
ContentItem({
Key key,
this.content,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
key: Key('__Content__${content.message}__'),
child: Column(
children: <Widget>[
Text('Message Here'),
Text(content.message.toString()),
],
),
);
}
}
~~ in InputArea. There is a TextEditingController and TextField.
onTap: () => contentsBloc.dispatch(AddContent(Content(_controller.text))),
~~
最后,这是我的Content类
@immutable
class Content extends Equatable {
final String message;
Content(this.message);
@override
String toString() => 'Content { message: $message }';
}
运行此代码时,可以看到CircleProgressIndicator()-当状态为ContentsLoading()-之后,将显示一个带有消息文本的容器。到目前为止,一切都很好。 但是,当我按下添加按钮并触发AddContent()事件后,新内容没有显示。
这是控制台日志。
AddContent { content: Content { message: new message } }
update contents : [Content { message: message }, Content { message: new message }]
我想添加容器,但是不起作用。
有人可以帮助我吗?在此先感谢:)
答案 0 :(得分:0)
我解决了这个问题。
我只是在扩展ContentsState的Bloc的ContentsLoaded类中添加了这一行。
class ContentsLoaded extends ContentsState {
final List<Content> contents;
// just add this line below.
ContentsLoaded([this.contents = const []]) : super([contents]);
@override
String toString() => 'ContentsLoaded { contents: $contents }';
}
谢谢。