Search code examples
flutterflutter-getxstate-managementflutter-state

Flutter - Getx update screen only after hot reload


There are 3 buttons and I want to change the color of the clicked button when I click it.

I manage the _currentFilter variable using obx and change the _currentFilter value using the changeFilter() function every time I click the button.

And the UI section used Obx to detect the changed value and change the color.

However, clicking each button changes the value of _currentFilter, but does not update the UI.

Only Hot Reload will change the color of the button text.

Why doesn't Obx detect that the _currentFilter value has changed in the UI?

I don't know why it is reflected in the UI only when doing Hot Reload.

Please Help.

UI

class FilterButtons extends GetView<TodoController> {
  const FilterButtons({Key? key}) : super(key: key);

  Widget filterButton(FilterEnum filter) {
    return TextButton(
      onPressed: () => controller.changeFilter(filter),
      child: Obx(() {
        final color = controller.filter == filter ? Colors.blueAccent : Colors.grey;
        return Text(filter.name, style: TextStyle(fontSize: 20, color: color));
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        filterButton(FilterEnum.ALL),
        filterButton(FilterEnum.ACTIVE),
        filterButton(FilterEnum.COMPLETED),
      ],
    );
  }
}

Controller

class TodoController extends GetxController {
  var _currentFilter = FilterEnum.ALL.obs;

  get filter => _currentFilter;

  void changeFilter(FilterEnum filter) {
    _currentFilter = filter.obs;
  }
}

Solution

  • if you assign new observable to _currentFilter, GetX won't get notified because previous observable that view is listening to didn't change. if you change it to:

    _currentFilter.value = filter;
    

    GetX fires a method called refresh() that refreshes the view.