Управление поставщиком для ListView Builder

#flutter #dart

#трепетание #дротик

Вопрос:

Я использую конструктор listview для создания списка на основе изменений в классе с помощью changenotifier. Я создаю список в provider, который обновляется при вызове функции сопряжения в классе bleservice. Затем это добавляет устройства в список устройств, а затем уведомляет слушателей об обновлении пользовательского интерфейса и отображении списка. Обновленный пользовательский интерфейс имеет кнопку, соответствующую индексу устройства в списке устройств, которая разрешает подключение.

 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'));
                  },
              ),
 

Поставщик:

 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();
    }
  }
}
 

При объединении listview builder с futurebuilder приложение выдает нулевую ошибку, и когда я запускаю его таким образом, страница вообще не загружается. Что я здесь делаю не так?

Ответ №1:

Вам необходимо указать количество элементов для 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();
  }
}
 

А также ваш код нуждается в дополнительных улучшениях.

Комментарии:

1. Я изменил ваш возврат с помощью return bleService. isPairing != null, и это сработало. Спасибо! Я также немного оптимизировал код.