我是新来的,如果有人能帮助我,我会很感激。我有一个下拉菜单,根据选择的下拉菜单改变屏幕的状态。它的工作与setstate很好,但我想改变我的应用程序的状态管理为getx。这是我的控制器:
List<String>clientType = [
'Anonymous',
'New',
'Existing Client',
if (getIt<Data>().isAdmin()) 'Existing Account',
].obs;
void changeClientType(String value) {
existingAccount = false;
if (value == 'Existing Account') {
existingAccount = true;
for (int i = 0; i < products.length; i++)
if (products[i].inventoryId.isEmpty) {
Get.snackbar(
'Error',
'Please note that you cannot use "Quick Add" while selling to '
'existing accounts. All "Quick Add" items will be skipped. '
'To undo, change "client type" back to '
'"$clientTypeDropdownValue"',
);
break;
}
}
if (value == 'New') {
newPersonInputFocusNode.requestFocus();
} else {
Get.focusScope.unfocus();
}
clientTypeDropdownValue = value;
update();
}
UI界面:
Widget _clientTypeDropdown() {
double options = getIt<Data>().isAdmin() ? 4 : 3;
return DropdownSearch<String>(
key: _clientTypeKey,
maxHeight: (55 * options).toDouble(),
mode: Mode.MENU,
showSelectedItem: true,
items: addSalesController.clientType,
label: 'Select Client Type',
onChanged:
(value) => addSalesController.changeClientType(value),
selectedItem: addSalesController.clientTypeDropdownValue,
);
}
Widget _newClientInput() {
return TextFormField(
controller: _newClientController,
focusNode: _newPersonInputFocusNode,
keyboardType: TextInputType.name,
textCapitalization: TextCapitalization.words,
decoration: textBorder('Enter new client's name'),
validator: (value) {
String val = value.trim();
if (val.isEmpty) return 'Enter new client's name';
if (val.length > 99) return 'Maximum length (100) exceeded';
return null;
},
);
}
Widget _existingClientDropdown() {
return FutureBuilder<void>(
future: _isOthersLoaded,
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.hasError) return Message();
if (snapshot.connectionState == ConnectionState.waiting)
return Loading();
double maxHeight = (_clients.length * 55).toDouble();
bool longerThanScreen = false;
if (maxHeight + 100 > MediaQuery.of(context).size.height) {
longerThanScreen = true;
maxHeight = MediaQuery.of(context).size.height - 100;
}
return DropdownSearch<Person>(
maxHeight: maxHeight == 0 ? 55 : maxHeight,
mode: Mode.MENU,
label: 'Select Client',
items: _clients,
onChanged: (value) => _clientNameDropdownValue = value,
selectedItem: _clientNameDropdownValue,
showClearButton: true,
validator: (v) => v == null ? 'Please select client' : null,
showSelectedItem: true,
compareFn: (item, selectedItem) => selectedItem == item,
emptyBuilder: (_, __) => EmptyDropdown(),
showSearchBox: longerThanScreen,
searchBoxDecoration: InputDecoration(
prefixIcon: Icon(Icons.search, size: 25),
labelText: 'Search',
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
),
),
);
},
);
}
Widget _existingAccountDropdown() {
return FutureBuilder<void>(
future: _isOthersLoaded,
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.hasError) return Message();
if (snapshot.connectionState == ConnectionState.waiting)
return Loading();
double maxHeight = (_companies.length * 55).toDouble();
bool longerThanScreen = false;
if (maxHeight + 100 > MediaQuery.of(context).size.height) {
longerThanScreen = true;
maxHeight = MediaQuery.of(context).size.height - 100;
}
return DropdownSearch<Company>(
maxHeight: maxHeight == 0 ? 55 : maxHeight,
mode: Mode.MENU,
label: 'Select Account',
items: _companies,
onChanged: (company) => _clientAccountDropdownValue = company,
selectedItem: _clientAccountDropdownValue,
showClearButton: true,
validator: (v) => v == null ? 'Please select account' : null,
showSelectedItem: true,
compareFn: (item, selectedItem) => selectedItem == item,
emptyBuilder: (_, __) => EmptyDropdown(),
showSearchBox: longerThanScreen,
searchBoxDecoration: InputDecoration(
prefixIcon: Icon(Icons.search, size: 25),
labelText: 'Search',
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
),
),
);
},
);
}
只要是与这个问题有关的建议,我们都欢迎。由于我也是GetX的新手,但我希望这将对您有所帮助。如果你想在应用程序的任何地方更新,你应该用GetxBuilder包装你的小部件。
例如:
Container(
child: GetBuilder<ControllerClassX>(
init: ControllerClassX(), //init this just one time in your page.
builder: (_) => Container(...), //this part will be updated if you trigger your function what has update(); keyword.
),
),
),
您应该用Obx或GetBuilder小部件包装您的小部件,以便在每次更改后重新构建小部件树。取决于你在控制器中的变量,你可以使用小部件。例如,对于可观察的小部件,你可以使用Obx(),对于普通变量,你可以使用getBuilder()。
反应性变量示例:
class Controller extends GetxController{
var count = 0.obs;
increment() => count++;
}
class Home extends StatelessWidget {
@override
Widget build(context) {
// Instantiate your class using Get.put() to make it available for all "child" routes there.
final Controller c = Get.put(Controller());
return Scaffold(
// Use Obx(()=> to update Text() whenever count is changed.
appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
...
}
}
正常变量示例:
class Controller extends GetxController {
int counter = 0;
void increment() {
counter++;
update(); // use update() to update counter variable on UI when increment be called
}
}
// On your Stateless/Stateful class, use GetBuilder to update Text when increment be called
GetBuilder<Controller>(
init: Controller(),
builder: (_) => Text(
'${_.counter}',
),
)