matt
matt

Reputation: 145

Flutter Read from disk and generate buttons

I am trying to read from a file and generate buttons for the page based on the contents.

if the file had "Tim","Eric","Andy" I would get three buttons with the respected names.

I found this page and it has been helpful. [Flutter Key value][1]. But I was unable to get it to work in a similar manner. I am able to read and write from the file but when I try to load them into the widget I am getting.

Expected a value of type 'List', but got one of type '_Future'

I have tried a few other methods to get this to work but this seems like the closest.

function I am trying to call

_loadplayers() async{
   List<Widget>? _loaded_players;
    final prefs = await SharedPreferences.getInstance();
    final List<String>? players = (prefs.getStringList('players'));
       players?.forEach((element) {
       _loaded_players?.add(buttons(text: element, style: ElevatedButton.styleFrom(primary: Colors.lightBlue,onPrimary: Colors.white),onPressed: () => _selectPlayers(element))) ;
      });

    // setState(() {
    // });
    // _loaded_players;
    return _loaded_players;
  }

how I am trying to call it.

Widget _buildContainer(BuildContext context)  {
    return Padding(
      padding: EdgeInsets.all(25),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          const Text(
              'Who is playing?',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 32.0,
                fontWeight: FontWeight.bold,
              )
          ),
          buttons(text: "Add Player",style: ElevatedButton.styleFrom(
            primary: Colors.lightBlue,
            onPrimary: Colors.white,
            //shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0),)
          ), onPressed: () => _NewPlayer(context)),
          const SizedBox(
            height: 25,
          ),
          Card(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children:
              _loadplayers()
            ),
          ),

I am fairly new to flutter so I am not too sure if I need to use the setState here or not cause it would only be loaded on start up. Any help is appreciated. [1]: https://docs.flutter.dev/cookbook/persistence/key-value

Upvotes: 0

Views: 59

Answers (1)

Advait
Advait

Reputation: 599

The load widgets function shouldn’t return null, if there are no players found, it should return an empty array. Here's the fix for that:

  Future<List<Widget>> loadplayers() async {
    List<Widget> _loaded_players = [];
    final prefs = await SharedPreferences.getInstance();
    final List<String>? players = (prefs.getStringList('players'));
       players?.forEach((element) {
       _loaded_players.add(buttons(text: element, style: ElevatedButton.styleFrom(primary: Colors.lightBlue,onPrimary: Colors.white),onPressed: () => _selectPlayers(element))) ;
      });
    return _loaded_players;
  }

Then, when you want to load the widgets, they should be loaded in a FutureBuilder as the function to get the players is an async function, so wrap the card in a FutureBuilder:

FutureBuilder(
  future: loadplayers(),
  builder: (context, snapshot){
    
    if(snapshot.connectionState == ConnectionState.done && snapshot.hasData){
      
      final players = snapshot.data as List<Widget>;
      
      return Card(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: players
        )
      );
        
    }else{
      return Container();
    }
    
  }
);

Upvotes: 1

Related Questions