Search code examples
androidflutterstate-managementriverpod

Question about Riverpod.. Show list of pdf files in a list view


This is my provider: (I believe the problem is here)

final fileListProvider = StateNotifierProvider<BookProvider, List>((ref) {

  return BookProvider();
});


class BookProvider extends StateNotifier<List>{
  BookProvider() : super([]);

  late String directory;
  List file = [];

  void listOfFiles() async {
    directory = (await getApplicationDocumentsDirectory()).path;
    file = io.Directory(directory).listSync();
  }
}

And this my widget class: (Consumer here)

class BookListView extends StatelessWidget {
  const BookListView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Expanded(

      child: Consumer(
        builder: (context, ref, _) {

          /// listen to provider variable.
          final file = ref.watch(fileListProvider);

          return GridView.builder(
              gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200,
                  childAspectRatio: 2 / 3,
                  crossAxisSpacing: 20,
                  mainAxisSpacing: 20),

              itemCount: file.length,

              itemBuilder: (BuildContext ctx, index) {
                String name = basename(file[index].toString());
                return BookListItem(bookName: name);
              }
          );
        }
      ),
    );
  }
}

What I want to do is to show all pdf files from the application folder into a list view. I think the problem is that the provider doesn't return the desired list! I'm new to Riverpod so I would really appreciate the help. Thanks

I also want to know what should I do if I wanted to split my provider into an individual class, because I can't make fileListProvider as a static when it's a global variable..


Solution

  • You should call listOfFiles in the constructor to initialize the state. Then in listOfFiles you should set state to a new value to change the state.

    class BookProvider extends StateNotifier<List>{
      BookProvider() : super([]) {
        listOfFiles();
      }
    
      late String directory;
    
      void listOfFiles() async {
        directory = (await getApplicationDocumentsDirectory()).path;
        state = io.Directory(directory).listSync();
      }
    }
    

    Regarding your second question about splitting the provider into an individual class, you can create a separate file for your provider and import it in your widget file. Since fileListProvider is a global variable, you can access it from anywhere when you import the file it's defined in.