首页 > 解决方案 > flutter listview listen to changes in file directory and rebuid the widget

问题描述

I'm building a download manager. How can listview widget listen to any changes such when download complete, the widget has to refresh automatically and when file is deleted the widget has to refresh automatically.

This is my code the secondtab which is responsible for download action once an action is fired from the first tab. The flutter_file_manager package is used fetch data in the directory. Share your thoughts on this?

import 'dart:io';
import 'package:VideoTube/tabs/share.dart';
import 'package:flutter/material.dart';
import 'package:flutter_file_manager/flutter_file_manager.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:provider/provider.dart';

class SecondTab extends StatefulWidget {
  SecondTab({Key key}) : super(key: key);

  @override
  _SecondTabState createState() => _SecondTabState();
}

class _SecondTabState extends State<SecondTab> {
  var files;
  ShareModel share;

  _SecondTabState({this.share});

  void getFiles() async {
    //asyn function to get list of files
    //List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
    //var root = storageInfo[0].rootDir; //storageInfo[1] for SD card, geting the root directory
    var fm = FileManager(root: Directory('/storage/emulated/0/VideoTube/')); //
    files = await fm.filesTree(
        //set fm.dirsTree() for directory/folder tree list
        // excludedPaths: ["/storage/emulated/0/VideoTube/"],
        // extensions: ["mp4"] //optional, to filter files, remove to list all,
        //remove this if your are grabbing folder list
        );
    
    
    setState(() {}); //update the UI
  }

  @override
  void initState() {
    getFiles(); //call getFiles() function on initial state.
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // super.build(context);
    return Scaffold(
        appBar: AppBar(
            title: Text("File/Folder list from SD Card"),
            backgroundColor: Colors.redAccent),
        body: Column(children: <Widget>[
          Flexible(
            flex: 3,
            child: Consumer<ShareProgress>(builder: (context, value, _) {
              return Padding(
                padding: EdgeInsets.all(15.0),
                child: FittedBox(
                  child: LinearPercentIndicator(
                    width: 100.0,
                    fillColor: Colors.white,
                    linearGradient: LinearGradient(
                      colors: [Colors.red, Colors.blue],
                    ),
                    lineHeight: 6.0,
                    percent: value.progress / 100,
                    center: Text(
                      "${value.progress}%",
                      style: TextStyle(fontSize: 5.0),
                    ),
                    trailing: Icon(
                      Icons.mood,
                      size: 5,
                    ),
                    linearStrokeCap: LinearStrokeCap.roundAll,
                    backgroundColor: Colors.grey,
                  ),
                ),
              );
            }

                // Container(
                //   child: Text('downloading.. ${value.progress}'),
                // ),
                ),
          ),
          FutureBuilder(
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              return Flexible(
                flex: 9,
                child: Container(
                  child: files == null
                      ? Text("Searching Files")
                      : ListView.builder(
                          //if file/folder list is grabbed, then show here
                          itemCount: files?.length ?? 0,
                          itemBuilder: (context, index) {
                            return Card(
                                child: ListTile(
                              title: Text(files[index].path.split('/').last),
                              leading: Icon(Icons.video_label),
                              trailing: Icon(
                                Icons.delete,
                                color: Colors.redAccent,
                              ),
                            ));
                          },
                        ),
                ),
              );
            },
          ),
        ]));
  }
}

This is how the UI looks like:

This is how UI looks like

标签: androidflutterlistviewdart

解决方案


我看到您正在使用 FutureBuilder,如果我正确理解了问题,StreamBuilder可能是正确的解决方案,它侦听流中的更改并在每次更改时重建子小部件。


推荐阅读