我是一位初学者,目前正在开发一个应用程序,该应用程序可以让我拍照,然后更新ListView以显示带有少量文字说明的照片。两者都放在卡内。我已经设法使其正常工作。最近,我进入了BLoC模式,并尝试在此应用程序中实现它。问题是即使快照包含添加的数据,ListView也不会显示流中的内容。
这是我的主要内容:
class MyApp extends StatelessWidget {
final LandscapeBloc _landscapeBloc = LandscapeBloc();
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: <String,WidgetBuilder>{
'/CameraPage': (BuildContext context)=> CameraScreen(cameras,_landscapeBloc),
},
initialRoute: '/',
home: HomePage(_landscapeBloc)
);
}
}
这是我的主页代码,其中包含暴露给streamOutput的ListView
class HomePage extends StatefulWidget {
final LandscapeBloc _landscapeBloc;
@override
_HomePageState createState() {
return _HomePageState();
}
HomePage(this._landscapeBloc);
}
class _HomePageState extends State<HomePage> {
List<LandscapeCard> list = [];
@override
void dispose() {
widget._landscapeBloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: widget._landscapeBloc.landscapeCardStream,
initialData: list,
builder: (BuildContext context,
AsyncSnapshot<List<LandscapeCard>> snapshot) {
print("[snaphot]" + snapshot.data.toString());
return (Column(children: <Widget>[
Flexible(
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
final LandscapeCard item = snapshot.data[index];
return Dismissible(
key: Key(item.landscapeImagePath),
onDismissed: (direction) {
widget._landscapeBloc.landscapeEvent
.add(DeleteEvent(index));
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("item suprrimé")));
},
child: item);
},
padding: const EdgeInsets.all(10.0)),
),
]));
}));
}
}
我知道当我打印(快照)包含所添加照片的列表时,StreamBuilder会收到数据原因。
我在这里输入数据;
class CardBuilder extends StatefulWidget {
final String _path;
final LandscapeBloc landscapeBloc;
CardBuilder(this._path, this._landscapeBloc);
@override
_CardBuilderState createState() {
// TODO: implement createState
return _CardBuilderState();
}
}
class _CardBuilderState extends State<CardBuilder> {
//TODO: stateful widget pour mis a jour UI quand on tape un texte
final TextEditingController descController = TextEditingController();
@override
void dispose() {
widget.landscapeBloc.dispose();
descController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
iconSize: 35.00,
onPressed: widget._onPressedBack),
),
DisplayMedia(widget._path),
Divider(
color: Colors.black,
height: 5,
),
TextField(
autofocus: false,
controller: descController,
maxLines: 5,
decoration: InputDecoration(
filled: false,
fillColor: Colors.black12,
border: InputBorder.none,
hintText: "put a description"),
),
Divider(
color: Colors.black,
height: 5,
),
IconButton(
icon: Icon(Icons.check_circle, color: Colors.black),
iconSize: 35.00,
onPressed: () {
final LandscapeCard landscapeCard= LandscapeCard(descController.text,widget._path);
widget._landscapeBloc.landscapeEvent.add(AddEvent(landscapeCard));
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(
builder: (BuildContext context) => HomePage(widget._landscapeBloc)
),(Route route)=> route==null);
})
]),
));
}
}
这是BLoc:
class LandscapeBloc {
List<LandscapeCard> list = [];
final StreamController _listLandscapeStateController = StreamController<List<LandscapeCard>>.broadcast();
StreamSink<List<LandscapeCard>> get _landscapeSink => _listLandscapeStateController.sink;
Stream<List<LandscapeCard>> get landscapeCardStream => _listLandscapeStateController.stream;
final StreamController<ManagingListEvent> _listLandscapeEventController = StreamController<ManagingListEvent>.broadcast();
StreamSink<ManagingListEvent> get landscapeEvent => _listLandscapeEventController.sink;
LandscapeBloc(){
_listLandscapeEventController.stream.listen(onManageEvent);
}
void onManageEvent(ManagingListEvent event){
if(event is DeleteEvent){
list.removeAt(event.indexDelete);
}
else{
list.add(event.landscapeCardAdd);
}
_landscapeSink.add(list);
print("[onManageEvent]"+event.landscapeCardAdd.landscapeImagePath+" "+event.landscapeCardAdd.landscapeDesc);
}
void dispose(){
_listLandscapeEventController.close();
_listLandscapeStateController.close();
}
}
最后是ManageListEvent类
abstract class ManagingListEvent{
int _indexS;
LandscapeCard _landscapeCardS;;
int get indexDelete => _indexS;
LandscapeCard get landscapeCardAdd => _landscapeCardS;
}
class DeleteEvent extends ManagingListEvent{
DeleteEvent(int index){
super._indexS=index;
}
}
class AddEvent extends ManagingListEvent{
AddEvent(LandscapeCard landscape){
super._landscapeCardS=landscape;
}
}
基本上,我想导航到一个新页面,在该页面中有刚刚拍摄的照片,添加一些描述,将其放在接收器中,然后导航回到HomePage。但是,即使ListView是通过快照接收的,它也不会随新的窗口小部件一起重新呈现。 预先感谢您的答复和时间