页面每次显示都会重新加载数据

问题描述 投票:0回答:1

git链接:[项目代码][1][1]:https://github.com/SanwarJW/multi_bloc_provider

描述:

我在 Flutter 应用程序中面临状态管理和导航问题。我有两个页面(HomePage 和 ImageListPage),我在其中使用了一个块。我将块实例从 HomePage 传递到 ImageListPage。但是,每次我导航到 ImageListPage 时,块实例似乎都会重新加载,从而导致意外行为。

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    final imageListBloc = BlocProvider.of<ImageListBloc>(context);

    return Scaffold(
        appBar: AppBar(title: const Text('Home')),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => ImageList(
                            imageListBloc: imageListBloc,
                          )));
            },
            child: const Text('Go to Image List'),
          ),
        ));
  }
}

我有一个 Flutter 应用程序,有两个页面(HomePage 和 ImageListPage),使用 bloc 实例。我将块实例从 HomePage 传递到 ImageListPage。但是,每次我导航到 ImageListPage 时,块实例都会重新加载,从而导致意外行为。

class ImageList extends StatefulWidget {
  final ImageListBloc imageListBloc;
  const ImageList({super.key, required this.imageListBloc});

  @override
  State<ImageList> createState() => _ImageListState();
}

class _ImageListState extends State<ImageList> {
  @override
  void initState() {
    super.initState();
    widget.imageListBloc.loadImages();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Image List')),
      body: Center(
        child: StreamBuilder<List<String>>(
          stream: widget.imageListBloc.imageListStream,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            }
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  return Text(snapshot.data![index]);
                },
              );
            } else {
              // Handle the case when data is not available
              return const Text('No data available');
            }
          },
        ),
      ),
    );
  }
}

这段Flutter Bloc代码定义了一个ImageListBloc,负责管理图像列表数据。它使用初始状态进行初始化并提供图像列表流。 loadImages 方法从 DataList 获取数据并将其发送到流

DataList dataList = DataList();

class ImageListBloc extends Bloc<ImageListEvent, ImageListState> {
  ImageListBloc() : super(ImageListInitial()) {}

  final _imageListController = StreamController<List<String>>.broadcast();
  Stream<List<String>> get imageListStream => _imageListController.stream;

  loadImages() async {
    if (!_imageListController.hasListener) {
      var dList = await dataList.gitListData();
      _imageListController.sink.add(dList);
    }
  }
}

我尝试过的:

通过构造函数传递 bloc 实例。调查导航路线是否存在任何潜在问题。检查块实例是否在导航中正确保留。预期结果:

我希望在 HomePage 和 ImageListPage 之间导航时无需重新加载即可维护 bloc 实例,从而确保一致的行为和状态管理。

任何有关如何解决此问题的见解或建议将不胜感激。谢谢!

flutter dart flutter-dependencies
1个回答
0
投票

我不明白将

ImageListBloc
实例传递到
ImageList
小部件的目的。

我看到你已经在 main() 中添加了它

BlocProvider<ImageListBloc>(create: (context) => ImageListBloc())
,然后只需调用
context.read<ImageListBloc>(); to get the BLoc instance within the widget tree

并且在您的小部件中根本没有使用 Bloc,您对 Bloc 的使用就像包含 StreamController 的随机类。

每次导航到

ImageList
时,它都会重新加载,因为在
loadImages()
方法运行之前,在
initState()
方法中调用
build
函数。结果,
StreamController
没有监听器,没有任何监听器,数据将被获取。

当您向后导航时,

ImageList
小部件将被释放,并且其侦听器将从流中删除。

如何修复

我的建议是正确使用 BLoc,向

ImageListState

添加更多状态
part of 'image_list_bloc.dart';

@immutable
sealed class ImageListState {}

final class ImageListInitial extends ImageListState {}
final class ImageListLoading extends ImageListState {}

final class ImageListLoaded extends ImageListState {
  final List<String> listData;
  ImageListLoaded ({required this.listData});
}

final class ImageListError extends ImageListState {}

ImageListBloc
(我在这里使用肘节作为简单的例子)

class ImageListBloc extends Cubit<ImageListState> {
  ImageListBloc() : super(ImageListInitial()) {}

  loadImages() async {
    emit(ImageListLoading());
    var dList = await dataList.gitListData();
    emit(ImageListLoaded(listData: dList));
  }
}

main()

BlocProvider<ImageListBloc>(create: (context) => ImageListBloc()..loadImages())

ImageList

class ImageList extends StatefulWidget {
  const ImageList({super.key});

  @override
  State<ImageList> createState() => _ImageListState();
}

class _ImageListState extends State<ImageList> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Image List')),
      body: BlocBuilder<ImageListBloc, ImageListState>(
        buildWhen: (old, current) {
          return current is ImageListLoading || current is ImageListLoaded || current is ImageListError;
        },
        builder: (context, state) {
          if(state is ImageListLoading) {
            return const CircularProgressIndicator();
          }

          if(state is ImageListError) {
            return Text('Error: ${snapshot.error}');
          }

          if(state is ImageListLoaded) {
            return ListView.builder(
              itemCount: (state).listData.length,
              itemBuilder: (context, index) {
                return Text((state).listData[index]);
              },
            );
          }

          return const Text('No data available');
        },
      ),
    );
  }
}

最后修正导航调用

 Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => ImageList())
 );
© www.soinside.com 2019 - 2024. All rights reserved.