英文:
Flutter UI is refreshed only after quick reload when using GetX
问题
我正在尝试使用GetX来更改所选的“Category”的颜色,该“Category”来自一组类别列表。当前,背景中的值正在按预期更改,但UI未刷新。
我尝试使用GetBuilder和Obx来更新UI,但结果相同。请查看下面的代码:
import 'package:flutter/material.dart';
class Category {
String name;
IconData icon;
Set<SubCategory> subcategories;
Category({
required this.name,
required this.icon,
required this.subcategories,
});
}
class SubCategory {
String name;
IconData icon;
SubCategory({
required this.name,
required this.icon,
});
}
import 'package:annual_budget/backend/model/spending_categories.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ExpensesController extends GetxController {
var expenseCategories = [].obs;
var expenseSubcategories = [].obs;
var selectedCategoryName = ''.obs;
var selectedSubcategoryName = ''.obs;
@override
void onInit() {
super.onInit();
expenseCategories.value = [
Category(
icon: Icons.all_inclusive_rounded,
name: 'Everyday',
subcategories: {
SubCategory(icon: Icons.local_grocery_store, name: 'Groceries'),
SubCategory(icon: Icons.restaurant, name: 'Restaurant'),
SubCategory(icon: Icons.delivery_dining, name: 'Food Order'),
},
),
Category(
icon: Icons.travel_explore,
name: 'Travel',
subcategories: {
SubCategory(
icon: Icons.airplane_ticket_outlined, name: 'Transportation'),
SubCategory(icon: Icons.food_bank_rounded, name: 'Food'),
SubCategory(icon: Icons.house, name: 'Accommodation'),
},
),
Category(
icon: Icons.pets_rounded,
name: 'Pet',
subcategories: {
SubCategory(icon: Icons.food_bank, name: 'Food'),
SubCategory(icon: Icons.medical_services, name: 'Veterinary'),
},
);
}
}
void setSubcategories(Set<SubCategory> subcategories, String categoryName) {
print(selectedCategoryName);
selectedCategoryName.value = categoryName;
expenseSubcategories.value = subcategories.toList();
print(selectedCategoryName);
refresh();
}
}
在上面的打印语句中,值按预期更改,但没有传播到UI。
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NewExpenseScreen extends StatelessWidget {
static const String route = 'new_expense_screen2';
final ExpensesController exc = Get.put(ExpensesController());
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: MaterialButton(
onPressed: () => Navigator.of(context).pop(),
child: const Icon(Icons.arrow_back_ios_new_rounded),
),
title: const Text('Add a new Expense'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Obx(
() => ListView.builder(
itemCount: exc.expenseCategories.length,
itemBuilder: (context, index) {
Category category = exc.expenseCategories[index];
return MaterialButton(
color: category.name == exc.selectedCategoryName.value
? ThemeData.dark().colorScheme.secondary
: ThemeData.dark().colorScheme.background,
onPressed: () {
exc.setSubcategories(
category.subcategories, category.name);
print(
'category ${category.name} isSelected: ${category.name == exc.selectedCategoryName.value} ');
FocusManager.instance.primaryFocus?.unfocus();
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Column(
children: [
Icon(
category.icon,
color: category.name ==
exc.selectedCategoryName.value
? Colors.black
: Colors.white,
),
Text(
category.name,
style: TextStyle(
color: category.name ==
exc.selectedCategoryName.value
? Colors.black
: Colors.white,
),
)
],
),
),
);
}),
),
),
],
),
),
);
}
}
在OnPressed中的打印语句显示所需的更改,但UI直到进行热重载时才刷新。
英文:
I'm trying to use GetX to change the color of a selected "Category", that comes from a list of categories. Currently, in the background the values are changing as expected, but the UI is not refreshed.
I tried both GetBuilder and Obx to have my UI updated, but with same outcome. Please see the code bellow:
import 'package:flutter/material.dart';
class Category {
String name;
IconData icon;
Set<SubCategory> subcategories;
Category({
required this.name,
required this.icon,
required this.subcategories,
});
}
class SubCategory {
String name;
IconData icon;
SubCategory({
required this.name,
required this.icon,
});
}
import 'package:annual_budget/backend/model/spending_categories.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ExpensesController extends GetxController {
var expenseCategories = [].obs;
var expenseSubcategories = [].obs;
var selectedCategoryName = ''.obs;
var selectedSubcategoryName = ''.obs;
@override
void onInit() {
super.onInit();
expenseCategories.value = [
Category(
icon: Icons.all_inclusive_rounded,
name: 'Everyday',
subcategories: {
SubCategory(icon: Icons.local_grocery_store, name: 'Groceries'),
SubCategory(icon: Icons.restaurant, name: 'Restaurant'),
SubCategory(icon: Icons.delivery_dining, name: 'Food Order'),
},
),
Category(
icon: Icons.travel_explore,
name: 'Travel',
subcategories: {
SubCategory(
icon: Icons.airplane_ticket_outlined, name: 'Transportation'),
SubCategory(icon: Icons.food_bank_rounded, name: 'Food'),
SubCategory(icon: Icons.house, name: 'Accomodation'),
},
),
Category(
icon: Icons.pets_rounded,
name: 'Pet',
subcategories: {
SubCategory(icon: Icons.food_bank, name: 'Food'),
SubCategory(icon: Icons.medical_services, name: 'Veterinary'),
},
),
];
}
void setSubcategories(Set<SubCategory> subcategories, String categoryName) {
print(selectedCategoryName);
selectedCategoryName.value = categoryName;
expenseSubcategories.value = subcategories.toList();
print(selectedCategoryName);
refresh();
}
}
In the above print statements, the value changes as expected, but without propagating to the UI
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NewExpenseScreen extends StatelessWidget {
static const String route = 'new_expense_screen2';
final ExpensesController exc = Get.put(ExpensesController());
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: MaterialButton(
onPressed: () => Navigator.of(context).pop(),
child: const Icon(Icons.arrow_back_ios_new_rounded),
),
title: const Text('Add a new Expense'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Obx(
() => ListView.builder(
itemCount: exc.expenseCategories.length,
itemBuilder: (context, index) {
Category category = exc.expenseCategories[index];
return MaterialButton(
color: category.name == exc.selectedCategoryName.value
? ThemeData.dark().colorScheme.secondary
: ThemeData.dark().colorScheme.background,
onPressed: () {
exc.setSubcategories(
category.subcategories, category.name);
print(
'category ${category.name} isSelected: ${category.name == exc.selectedCategoryName.value} ');
FocusManager.instance.primaryFocus?.unfocus();
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Column(
children: [
Icon(
category.icon,
color: category.name ==
exc.selectedCategoryName.value
? Colors.black
: Colors.white,
),
Text(
category.name,
style: TextStyle(
color: category.name ==
exc.selectedCategoryName.value
? Colors.black
: Colors.white,
),
)
],
),
),
);
}),
),
),
],
),
),
);
}
}
The print statement from the OnPressed shows the desired changes, but the UI is still not refreshed until I do a hot reload.
答案1
得分: 1
请检查下面的代码:
void setSubcategories(Set<SubCategory> subcategories, String categoryName) {
print(selectedCategoryName);
selectedCategoryName.value = categoryName;
expenseSubcategories.value = subcategories.toList();
print(selectedCategoryName);
expenseCategories.refresh();
}
你需要在 setSubcategories
方法中刷新 expenseCategories
列表。
当你需要更新多个列表时,应该使用 GetBuilder
。
英文:
Please check out below code.
void setSubcategories(Set<SubCategory> subcategories, String categoryName) {
print(selectedCategoryName);
selectedCategoryName.value = categoryName;
expenseSubcategories.value = subcategories.toList();
print(selectedCategoryName);
expenseCategories.refresh();
}
You have to refresh the expenseCategories
list in the setSubcategories
method.
When you need to update multiple lists, you should use getbuilder
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论