Управление состоянием Flutter и Getx — Изменения в представлении списка

#flutter #dart #get #flutter-getx

Вопрос:

Создание одного торгового приложения с использованием flutter с управлением состоянием Getx. Я не знаю, как создать контроллер для каждого элемента в списке. Таким образом, любые изменения в конкретном элементе списка будут перезагружать только этот элемент, а не весь список.

введите описание изображения здесь

Если я нажму контейнер «Новый заказ», другой контейнер(«Заказ подтвержден», «Завершен») также перестроится (перестроится весь список).

Моя Модель :

 import 'package:get/get.dart';

class TabModel {
  late String tabName;
  RxBool isSelected = false.obs;

  TabModel(this.tabName);
}
 

Мой Контроллер :

 import 'package:get/get.dart';
import 'package:super_mart_merchant/view/orders/view_models/tab_model.dart';
import 'package:collection/collection.dart';

class TabViewController extends GetxController{
  RxList<TabModel> tabModels = <TabModel>[].obs;
  @override
  void onInit() {
    super.onInit();
    loadVal('New Order',true);
    loadVal('Order Confirmed',false);
    loadVal('Order Declined',false);
    loadVal('Completed',false);
  }

  void loadVal(String name,bool isSelected){
    TabModel tabModel = TabModel(name);
    tabModel.isSelected.value = isSelected;
    tabModels.add(tabModel);
  }

  void onClick(int pos){
    TabModel tabModel =   tabModels[pos];
    if(!tabModel.isSelected.value){
      TabModel? previousTabModel =  tabModels.firstWhereOrNull((element) => element.isSelected.value);
      if(previousTabModel != null){
        previousTabModel.isSelected.value = false;
      }
      tabModel.isSelected.value = true;

    }

  }
}
 

Binding:

 import 'package:get/get.dart';
import 'package:super_mart_merchant/view/orders/controllers/tab_controller.dart';

class TabControllerBinding implements Bindings{
  @override
  void dependencies() {
    Get.lazyPut<TabViewController>(() => TabViewController());

  }
}
 

Вид :

 class TabView extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return GetX<TabViewController>(
      builder: (TabViewController tabController) {
        print('Object called : ${tabController.toString()}');
        return Container(
          height: 55,
          alignment: Alignment.center,
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            itemBuilder: (ctx, int index) {
              if (tabController.tabModels[index].isSelected.value) {
                return SelectedOrderStatusComponents(
                    tabController.tabModels[index],
                    index);
              }
              return GestureDetector(
                onTap: (){
                  tabController.onClick(index);
                },
                child: UnSelectedOrderStatusComponents(
                    tabController.tabModels[index],
                    index),
              );
            },
            itemCount: tabController.tabModels.length,
          ),
        );
      },
    );
  }
}
 

В Провайдере у нас есть варианты для этого. Я не знаю, как это сделать в Getx. Большое спасибо!!!.

Ответ №1:

Это мой первый ответ здесь, поэтому я надеюсь, что он соответствует стандарту, а также не слишком поздно для ваших проблем. Для вашей первой проблемы: хотите, чтобы каждая вкладка не перестраивалась после перехода по вкладкам. Вы можете преобразовать виджет вкладки в виджет с отслеживанием состояния и добавить AutomaticKeepAliveClientMixin его, чтобы предотвратить его восстановление после навигации. Что-то вроде этого:

 class TabView extends StatefulWidget {
  TabView ({Key? key}) : super(key: key);

  @override
  _TabViewState createState() => _TabViewState();
}

class _TabViewState extends State<TabView>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Container();
  }
  
  @override
  bool get wantKeepAlive => true;
}
 

Для вашей второй проблемы, чтобы просто перезагрузить элемент, а не весь список, вы можете обернуть каждый элемент Obx или GetBuilder и дать ему тег база по индексу или идентификатор каждого элемента, но я не рекомендую делать это со GetX довольно быстро в восстановлении, это только перестроить где изменились и слишком много GetBuilder на одной странице может повлиять на производительность.

 return GestureDetector(
     onTap: (){
          tabController.onClick(index);
     },
     child: GetBuilder<TabViewController>(
          id: "item"   tabController.tabModels[index].id,
          builder: (controller) {
              return UnSelectedOrderStatusComponents(
                   tabController.tabModels[index],
                   index);
          }
     )
);
 

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

1. Извините за поздний ответ. Спасибо за ваш ценный ответ. Основываясь на вашем втором ответе, я решил свою проблему. Обертывание с помощью getX каждого элемента вместо всего списка.