как предотвратить перестройку showModalBottomSheet в Flutter?

Вопрос или проблема

Я использовал Futurebuilder для получения адресов пользователей в showmodalbottomsheet, все работает нормально, но при прокрутке он обновляется и делает ненужные запросы из-за future builder.

Я хочу предотвратить перестройку modalbottom sheet, чтобы он не обновлялся при прокрутке…

Надеюсь, моя точка зрения ясна…

Чтобы объяснить подробнее, я создал этот демонстрационный пример, где цвет меняется при прокрутке

Future<dynamic> showAddressModalBottomSheet(BuildContext context) async
  {
     return  showModalBottomSheet(
         context: context, builder: (_){

      return Container(
        color: Color.fromRGBO(Random().nextInt(255), Random().nextInt(255), Random().nextInt(255), 1),
      );

    });

  }

Ответ или решение

Чтобы предотвратить перезагрузку showModalBottomSheet в Flutter, особенно когда используется FutureBuilder, необходимо принимать во внимание несколько ключевых аспектов, которые помогут обеспечить плавность работы интерфейса и минимизировать ненужные вызовы.

1. Используйте StatefulWidget для управления состоянием

Первое решение, которое можно предложить — это использование StatefulWidget вместо FutureBuilder внутри вашего showModalBottomSheet. Это позволит вам сохранить состояние данных и избежать их повторной загрузки при прокрутке.

class AddressModal extends StatefulWidget {
  @override
  _AddressModalState createState() => _AddressModalState();
}

class _AddressModalState extends State<AddressModal> {
  Future<List<Address>>? _addresses;

  @override
  void initState() {
    super.initState();
    _addresses = fetchUserAddresses();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Address>>(
      future: _addresses,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        }
        if (snapshot.hasError) {
          return Center(child: Text('Ошибка загрузки адресов'));
        }

        final addresses = snapshot.data ?? [];
        return ListView.builder(
          itemCount: addresses.length,
          itemBuilder: (context, index) => ListTile(
            title: Text(addresses[index].name),
          ),
        );
      },
    );
  }
}

Здесь мы загружаем адреса один раз в методе initState, и они остаются в памяти, предотвращая повторные запросы при прокрутке.

2. Кэширование данных

Вы также можете рассмотреть возможность кэширования данных, полученных с помощью FutureBuilder или другого механизма. Храните загруженные адреса в переменной состояния. Если данные уже были загружены, используйте их повторно:

class AddressModal extends StatefulWidget {
  @override
  _AddressModalState createState() => _AddressModalState();
}

class _AddressModalState extends State<AddressModal> {
  List<Address>? _addresses;

  Future<void> fetchUserAddresses() async {
    // Логика загрузки адресов
    _addresses = await fetchAddressesFromApi();
  }

  @override
  void initState() {
    super.initState();
    fetchUserAddresses();
  }

  @override
  Widget build(BuildContext context) {
    return _addresses == null
        ? Center(child: CircularProgressIndicator())
        : ListView.builder(
            itemCount: _addresses!.length,
            itemBuilder: (context, index) => ListTile(
              title: Text(_addresses![index].name),
            ),
          );
  }
}

3. Использование Provider или других управлений состоянием

Использование архитектурного паттерна управления состоянием, такого как Provider, Bloc или Riverpod, может значительно упростить работу с состоянием данных. Это поможет избежать ненужных перезагрузок интерфейса:

  1. Создайте свой класс состояния, который будет загружать адреса.
  2. Используйте этот класс в showModalBottomSheet, чтобы получить данные.

Пример с использованием Provider:

class AddressProvider with ChangeNotifier {
  List<Address>? _addresses;

  Future<void> loadAddresses() async {
    if (_addresses == null) {
      _addresses = await fetchAddressesFromApi();
      notifyListeners();
    }
  }

  List<Address>? get addresses => _addresses;
}

// Внутри вашего метода
showModalBottomSheet(context) {
  return ChangeNotifierProvider(
    create: (_) => AddressProvider()..loadAddresses(),
    child: Consumer<AddressProvider>(
      builder: (context, provider, child) {
        if (provider.addresses == null) {
          return Center(child: CircularProgressIndicator());
        }
        return ListView.builder(
          itemCount: provider.addresses!.length,
          itemBuilder: (context, index) => ListTile(
            title: Text(provider.addresses![index].name),
          ),
        );
      },
    ),
  );
}

Заключение

Предотвращение лишней перезагрузки showModalBottomSheet в Flutter требует применения правильных паттернов управления состоянием. Использование StatefulWidget, кэширования и управления состоянием с помощью таких решений, как Provider, позволит вам избежать ненужных запросов и сделать интерфейс более плавным и отзывчивым. Следуя приведённым рекомендациям, вы сможете улучшить пользовательский опыт в вашем приложении.

Оцените материал
Добавить комментарий

Капча загружается...