英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论