简体   繁体   English

如何从 flutter 中的另一个小部件刷新列表视图?

[英]How to refresh a listview from another widget in flutter?

I am new to flutter, and I am trying to refresh my list of files after adding a file in my PDF app.我是 flutter 的新手,在我的 PDF 应用程序中添加文件后,我试图刷新我的文件列表。 Listview and add button I am using are in different widgets.我正在使用的列表视图和添加按钮位于不同的小部件中。 Refresh function I have used is working for the delete button which is in the same widget as listview and gives error for the add button which is in a different widget from the List view.刷新 function 我使用的是删除按钮,该按钮与列表视图位于同一小部件中,而添加按钮则与列表视图位于不同的小部件中。 In both instances,I am trying to update the List view.在这两种情况下,我都在尝试更新列表视图。

` `

class ListFiles extends StatefulWidget {
  const ListFiles({Key? key}) : super(key: key);

  @override
  State<ListFiles> createState() => _ListFilesState();
}

class _ListFilesState extends State<ListFiles> {
  final storage = FirebaseStorage.instance;
  late Future<ListResult> futureFiles;

  String pathPDF = "";

  final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    futureFiles = FirebaseStorage.instance.ref('files').listAll();
  }

  @override
  Widget build(BuildContext context) => SizedBox(
        height: 450,
        child: RefreshIndicator(
          onRefresh: onRefresh,
          child: FutureBuilder<ListResult>(
            future: futureFiles,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final files = snapshot.data!.items;

                return  ListView.builder(
                    itemCount: files.length,
                    itemBuilder: (context, index) {
                      final file = files[index];

                      return ListTile(
                        title: Text(file.name),
                        onTap: ()  async {
                          String url = await getFirebaseDownUrl(file);
                          Navigator.push(context,
                              MaterialPageRoute(builder: (BuildContext context) =>
                                  Scaffold(
                                      appBar: AppBar(
                                          title: Text(file.name),
                                        backgroundColor: Colors.red,
                                      ),
                                      body: SfPdfViewer.network(
                                        url,
                                        key: _pdfViewerKey,
                                      )
                                  ),
                              ),
                          );
                        },
                        trailing: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            IconButton(
                              onPressed: () {
                                _dialogBuilder(context, file);
                              },
                              icon: const Icon(
                                Icons.delete,
                                color: Colors.red,
                              ),
                            ),
                          ],
                        ),
                      );
                    }
                );
              } else if (snapshot.hasError) {
                return Column(
                  children: [
                    ListTile(
                      leading: const Icon(
                        Icons.error,
                        color: Colors.redAccent,
                      ),
                      title: const Text('Error occurred'),
                      trailing: IconButton(
                        onPressed: () {
                          setState(() {
                            onRefresh();
                          });
                        },
                        icon: const Icon(
                          Icons.refresh,
                          color: Colors.blue,
                        ),
                      ),
                    ),
                  ],
                );
              } else {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          ),
        ),
      );

  Future<String> getFirebaseDownUrl(Reference ref) async {
    print(await ref.getDownloadURL());
    return ref.getDownloadURL();
  }

  Future downloadFile(Reference ref) async {
    List<int> textBytes = utf8.encode('{$ref}');
    Uint8List data = Uint8List.fromList(textBytes);
    String mimeType = "application/pdf";

    DocumentFileSavePlus.saveFile(data, ref.name, mimeType);

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Downloaded ${ref.name} successfully')),
    );
  }

  Future deleteFile(Reference ref) async {
    // Create a reference to the file to delete
    final storageRef = FirebaseStorage.instance.ref();
    final deleteRef = storageRef.child(ref.fullPath);

    // Delete the file
    await deleteRef.delete();

    // setState(() {
    //   futureFiles = FirebaseStorage.instance.ref('files').listAll();
    // });
    // build(context);

    onRefresh();

    //  WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));

    ScaffoldMessenger.of(context).showSnackBar(
      // SnackBar(content: Text('Deleted file ${ref.name}')),
      SnackBar(
        content: Row(
          children: [
            Text('${ref.name} deleted successfully'),
            const Spacer(
              flex: 2,
            ),
            TextButton(
              onPressed: () {
                onRefresh();
              },
              child: const Text(
                'Refresh',
                style: TextStyle(color: Colors.blue),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _dialogBuilder(BuildContext context, Reference file) {
    return showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Warning'),
          content: const Text('Are you sure you want to delete the file?'),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('NO', style: TextStyle(color: Colors.green)),
            ),
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
                deleteFile(file);
              },
              child:
                  const Text('YES', style: TextStyle(color: Colors.redAccent)),
            ),
          ],
        );
      },
    );
  }

  Future onRefresh() async {
    print('Page refreshing...');

    setState(() {
      futureFiles = FirebaseStorage.instance.ref('files').listAll();
      print('Status updated...');
    });

    build(context);
    // ListFiles();
    print('Page refreshed...');
  }
}

class AddButton extends StatefulWidget {
  const AddButton({Key? key}) : super(key: key);

  @override
  State<AddButton> createState() => _AddButtonState();
}

class _AddButtonState extends State<AddButton> {
  PlatformFile? pickedFile;
  UploadTask? uploadTask;

  late Future<ListResult> futureFiles;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(20.0),
          child: FloatingActionButton(
            backgroundColor: const Color(0xFFFF1D1D),
            foregroundColor: Colors.white,
            onPressed: () async {
              addFile();
            },
            child: const Icon(Icons.add),
          ),
        ),
      ],
    );
  }

  Future addFile() async {
    final result = await FilePicker.platform.pickFiles();
    if (result == null) return;

    setState(() {
      pickedFile = result.files.first;
    });

    uploadFile();
  }

  Future uploadFile() async {
    final path = 'files/${pickedFile!.name}';
    final file = File(pickedFile!.path!);
    final ref = FirebaseStorage.instance.ref().child(path);
    final _ListFilesState Listfile = new _ListFilesState();

    setState(() {
      uploadTask = ref.putFile(file);
    });

    setState(() {
      uploadTask = null;
    });

    if (pickedFile != null) {
      addtoFirestore();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Row(
            children: [
              const Text('File uploaded successfully!'),
              const Spacer(
                flex: 2,
              ),
              TextButton(
                onPressed: () => Listfile.onRefresh(),
                child: const Text(
                  'Refresh',
                  style: TextStyle(color: Colors.blue),
                ),
              ),
            ],
          ),
        ),
      );
    }
  }

` `

This is the response msg I get when refresh button of the snackbar is clicked.这是单击快餐栏的刷新按钮时收到的响应消息。

enter image description here Is this implementation correct? enter image description here这个实现是否正确? Thank you for your time.感谢您的时间。

add a callback function to your ListFiles class:将回调 function 添加到您的 ListFiles class:

    setStateAddedNewClient(  item ) {
    setState(() {
      futureFiles.add(item);
      
    });
  }

then add function parameter to your AddButton class:然后将 function 参数添加到您的 AddButton class:

final  Function(dynamic) callback;
const AddButton({Key? key ,required this.callback }) : super(key: key);

and send file to callback function in your addFile function.并将文件发送到您的 addFile function 中的回调 function。

  Future addFile() async {
    final result = await FilePicker.platform.pickFiles();
    if (result == null) return;

    setState(() {
      pickedFile = result.files.first;
      callback(result.files.first);
    });

    uploadFile();
  }

you can use a HookWidget你可以使用 HookWidget

useEffect((() {
//request that you fetch data to listview
      context.read<Cubit>().getListRequest();
      return null;
    }), [dependenciesFromAnotherWidgetToRefreshList]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM