0

I want to listen to the current theme permanently because I had some issues with the systemchrom, so I found a workaround for that where I call a BlocProvider.of inside my Widget build. In general, it works perfectly fine now, but is this a clean solution or not a good practice, if last, is there a better way of listening to a SystemUiOverlayStyle permanently?

@override
  Widget build(BuildContext context) {
BlocProvider.of<SysUiCubit>(context).changeTheme(context, isDarkMode);
 return BlocBuilder<SysUiCubit, SysUiState>(
      builder: (context, state) {
        return AnnotatedRegion<SystemUiOverlayStyle>(

I added a small logic inside the build so the BlocProvider only gets called when the theme changes:

bool buildOnce =false;
  @override
  Widget build(BuildContext context) {

    bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
    if(!buildOnce){
      setPrev(Theme.of(context).brightness == Brightness.dark);
    buildOnce=true;
    }
    if(darkmodePrev != isDarkMode){
      BlocProvider.of<SysUiCubit>(context).changeTheme(context, isDarkMode);
      buildOnce=false;
    }

Same thing I asked myself on another point at my app:

  @override
  Widget build(BuildContext context) {
    final todo= context.watch<TodoListCubit>().state.todo;

    return BlocListener<TodoListCubit, TodoListState>(
        listener: (context, state) {

Here I have a todo list where I call context.watch inside my build function - same question - I didn't find a cleaner solution for updating the todo list every time the widget rebuilds, so is this okay or a bad practice?

1 Answer 1

2

Bad Practice

Defining a function inside the build

Good Practice (To be followed)

Define a function outside the build and call it inside the function which will help you rebuild the widget if needed.


For your problem, I suggest you emit changes when the theme changes and rebuild the widget using buildWhen instead of embedding this work around inside the build.

That would be considered more cleaner code, If this is what you are looking for.


Use something like, example from the official docs:

class ThemeCubit extends Cubit<ThemeData> {
  /// {@macro brightness_cubit}
  ThemeCubit() : super(_lightTheme);

  static final _lightTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.white,
    ),
    brightness: Brightness.light,
  );

  static final _darkTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.black,
    ),
    brightness: Brightness.dark,
  );

  /// Toggles the current brightness between light and dark.
  void toggleTheme() {
    emit(state.brightness == Brightness.dark ? _lightTheme : _darkTheme);
  }
}

BlocBuilder<BlocA, BlocAState>(
  buildWhen: (previousState, state) {
    // return true/false to determine whether or not // 👈 add your logic here
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)
Sign up to request clarification or add additional context in comments.

5 Comments

Please find the updated post, hope it helps
Never used buldWhen before so this is completly wrong isnt it? : buildWhen: (prevState, state){ bool isDarkMode = Theme.of(context).brightness == Brightness.dark; if(!buildOnce){ setPrev(Theme.of(context).brightness == Brightness.dark); buildOnce=true; } if(darkmodePrev != isDarkMode){ BlocProvider.of<SysUiCubit>(context).changeTheme(context, isDarkMode); buildOnce=false; return true; }else{ return false; } }
I think my problem is, I dont call the BloCProvider somewhere else again only inside widget build, so when I remove this, BlocBuild will not rebuild anyway
I wouldn't say It is not complelty wrong, i would rather say , using buildwhen your code would be more clean and you follow the industry standards and more importantly you can avoid using the work around inside the build method
Any reference on why is it bad to define functions inside the build method?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.