问题描述
我正在尝试编写一个页面,该页面从firebase存储文件夹下载图像并将其显示在网格中。第一次导航到此页面时,我对此没有任何问题。但是,一旦我导航到另一个页面然后又返回到该页面,图像将不再加载。函数getimage()
是加载图像的工具。它在initState()
中被调用。是因为页面第一次打开时仅被调用一次?
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
// Getting arguments passed in while calling Navigator.pushNamed
final args = settings.arguments;
switch (settings.name) {
...
case '/stichpage':
// Validation of correct data type
return MaterialPageRoute(
builder: (_) => ImagesScreen(),);
...
}
import 'package:Flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'dart:typed_data';
import 'dataholder.dart';
class ImagesScreen extends StatelessWidget {
Widget makeImagesGrid() {
return GridView.builder(
itemCount: "objectname".length,gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),itemBuilder: (context,index) {
return ImageGridItem(index);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.lightBlue,elevation: 5,title: Text('Image Stitching'),centerTitle: true,),body: Container(
child: makeImagesGrid(),bottomNavigationBar: BottomAppBar(
color: Colors.grey[200],child: Row(
children: [
Spacer(),IconButton(icon: Icon(Icons.save),onpressed: () {}),],floatingActionButton: FloatingActionButton.extended(
backgroundColor: Colors.lightBlue,foregroundColor: Colors.white,onpressed: () {},icon: Icon(Icons.burst_mode),label: Text('Stitch'),floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,);
}
}
class ImageGridItem extends StatefulWidget {
int _index;
ImageGridItem(int index) {
this._index = index;
}
@override
_ImageGridItemState createState() => _ImageGridItemState();
}
class _ImageGridItemState extends State<ImageGridItem> {
Uint8List imageFile;
StorageReference photosReference =
FirebaseStorage.instance.ref().child("images");
getimage() {
if (!requestedindexes.contains(widget._index)) {
int maxSize = 7 * 1024 * 1024;
photosReference
.child("cell${widget._index}.png")
.getData(maxSize)
.then((data) {
this.setState(() {
imageFile = data;
});
imageData.putIfAbsent(widget._index,() {
return data;
});
}).catchError((error) {
debugPrint(error.toString());
});
requestedindexes.add(widget._index);
}
}
Widget decideGridTileWidget() {
if (imageFile == null) {
return Center(child: Text(""));
} else {
return Image.memory(
imageFile,fit: BoxFit.cover,);
}
}
@override
void initState() {
super.initState();
if (!imageData.containsKey(widget._index)) {
getimage();
} else {
this.setState(() {
imageFile = imageData[widget._index];
});
}
}
@override
Widget build(BuildContext context) {
return GridTile(child: decideGridTileWidget());
}
}
还有保存图像数据的代码:
import 'dart:typed_data';
Map<int,Uint8List> imageData = {};
List<int> requestedindexes = [];
解决方法
当您推送到另一个视图时,先前的视图将保留在Navigator
中,因此当您弹出该视图时,它确实会重建,但不会再次调用initState
。
如果您想在弹出屏幕后又回到主屏幕时实际进行操作,则需要实施RouteObserver
,例如
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),navigatorObservers: [routeObserver],home: Screen1(),routes: {
'screen2': (context) => Screen2(),'screen3': (context) => Screen3(),},);
}
}
一旦您将其设置为主要内容,就需要屏幕为RouteAware
class Screen3 extends StatefulWidget {
@override
_Screen3State createState() => _Screen3State();
}
class _Screen3State extends State<Screen3> with RouteAware {
@override
void didChangeDependencies() {
super.didChangeDependencies();
RouteObserverProvider.of(context).subscribe(this,ModalRoute.of(context));
}
@override
void dispose() {
RouteObserverProvider.of(context).unsubscribe(this);
super.dispose();
}
@override
void didPush() {
print('didPush Screen3');
}
@override
void didPopNext() {
print('didPopNext Screen3');
}
}
您实际需要的是didPopNext
。
David Anaya在Medium中有一篇不错的文章,您可以寻找here