RealRK
RealRK

Reputation: 317

Managing a provider for ListView Builder

I'm using a listview builder to create a list based on changes in a class with changenotifier. I create a list in provider which gets updated upon calling pairing function in bleservice class. This then adds devices to devices list and then notifies listeners to update the UI and display the list. The updated UI has a button corresponding the index of device in devicesList which allows the connection.

ListView.builder(
                itemBuilder: (context, index) {
                  if (bleService.isPairing){
                  List<Container> containers = new List<Container>();
                  for (BluetoothDevice device in bleService.devicesList) {
                    containers.add(
                      Container(
                        height: 50,
                        child: Row(
                          children: <Widget>[
                            Expanded(
                              child: Column(
                                children: <Widget>[
                                  Text(device.name == ''
                                      ? '(unknown device)'
                                      : device.name),
                                  Text(device.id.toString()),
                                ],
                              ),
                            ),
                            FlatButton(
                                color: Colors.blue,
                                child: Text(
                                  'Connect',
                                  style: TextStyle(color: Colors.white),
                                ),
                                onPressed: () {
                                  bleService.connectDevice(device);
                                }),
                          ],
                        ),
                      ),
                    );
                  }
                  return ListView(
                    padding: const EdgeInsets.all(8),
                    children: <Widget>[
                      ...containers,
                    ],
                  );
                }
                  else
                    return Container(child: Text('Disconnected'));
                  },
              ),

Provider:

class BleService with ChangeNotifier{
    List<BluetoothDevice> _devicesList = [];
    List<BluetoothDevice> get devicesList {
        return [..._devicesList];
    }

    _addNewDeviceTolist(final BluetoothDevice device) {
    if (!_devicesList.contains(device)) {
      _devicesList.add(device); //stream/upload this to BleScreen as more devices get added
      notifyListeners();
    }
  }
}

When combining the listview builder with a futurebuilder, the app gives me a null error, and when I run it like this, the page doesn't load at all. What am I doing wrong here?

Upvotes: 0

Views: 1039

Answers (1)

Ishanga Vidusha
Ishanga Vidusha

Reputation: 304

You need to specify the item count for ListView.builder():

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  BleService bleService;
  @override
  Widget build(BuildContext context) {
    bleService = Provider.of<BleService>(context);
    return bleService != null ? Container(
      child: ListView.builder(
        itemCount: bleService.isPairing ? bleService.devicesList.length : 0,
        itemBuilder: (context, index) {
          return bleService.isPairing ? bleService.devicesList.map((BluetoothDevice device) => Container(
            height: 50,
            child: Row(
              children: <Widget>[
                Expanded(
                  child: Column(
                    children: <Widget>[
                      Text(device.name == ''? '(unknown device)' : device.name),
                      Text(device.id.toString()),
                    ],
                  ),
                ),
                FlatButton(
                  color: Colors.blue,
                  child: Text(
                    'Connect',
                    style: TextStyle(color: Colors.white),
                  ),
                  onPressed: () {
                    bleService.connectDevice(device);
                  }
                ),
              ],
            ),
          )).toList() : Container(child: Text('Disconnected'));
        }
      ),
    ) : Container();
  }
}

And also your code needs more improvements.

Upvotes: 1

Related Questions