Flutter 和 Getx 状态管理——列表视图的变化
Flutter and Getx State Management - List View Changes
使用带有 Getx 状态管理的 flutter 创建一个购物应用程序。我不知道如何为列表中的每个元素创建一个控制器。因此,列表中特定元素的任何更改都将仅重新加载该元素,而不是整个列表重新加载。
如果我单击“新订单”容器,其他容器(“已确认订单”、“已完成”)也会重建(重建整个列表视图)。
我的模特:
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;
}
}
}
绑定:
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,
),
);
},
);
}
}
在 Provider 中,我们有这方面的选项。我不知道如何在 Getx 中做到这一点。非常感谢!!!
第一次在这里回答,希望能达到标准,也不要来不及回答你的问题。
对于您的第一个问题:希望在标签中导航后不重建每个标签。您可以将 Tab 小部件转换为有状态小部件并添加 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
中并根据索引或 ID 给它一个标签每个项目,但我不建议这样做,因为 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);
}
)
);
使用带有 Getx 状态管理的 flutter 创建一个购物应用程序。我不知道如何为列表中的每个元素创建一个控制器。因此,列表中特定元素的任何更改都将仅重新加载该元素,而不是整个列表重新加载。
如果我单击“新订单”容器,其他容器(“已确认订单”、“已完成”)也会重建(重建整个列表视图)。
我的模特:
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;
}
}
}
绑定:
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,
),
);
},
);
}
}
在 Provider 中,我们有这方面的选项。我不知道如何在 Getx 中做到这一点。非常感谢!!!
第一次在这里回答,希望能达到标准,也不要来不及回答你的问题。
对于您的第一个问题:希望在标签中导航后不重建每个标签。您可以将 Tab 小部件转换为有状态小部件并添加 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
中并根据索引或 ID 给它一个标签每个项目,但我不建议这样做,因为 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);
}
)
);