#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 каждого элемента вместо всего списка.