admin管理员组

文章数量:1401922

I'm working with Flutter Bloc for state management. I have a ThemeBloc that toggles between light and dark modes, and I want to trigger AppBloc to perform an action whenever the theme changes. However, changes in ThemeBloc do not reflect in AppBloc.

theme_bloc.dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';

part 'theme_event.dart';
part 'theme_state.dart';

class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
  ThemeMode _themeMode = ThemeMode.system;

  ThemeBloc() : super(ThemeStateInitial(themeMode: ThemeMode.system)) {
    on<ThemeEventToggle>((event, emit) {
    _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
    emit(ThemeStateChanged(themeMode: _themeMode));
  });
 }
}

theme_event.dart

part of 'theme_bloc.dart';

sealed class ThemeEvent extends Equatable {
   const ThemeEvent();

  @override
  List<Object?> get props => [];
}

class ThemeEventToggle extends ThemeEvent {
  const ThemeEventToggle();
 }

theme_state.dart

part of 'theme_bloc.dart';

sealed class ThemeState extends Equatable {
   final ThemeMode themeMode;
   const ThemeState({required this.themeMode});

   @override
   List<Object> get props => [themeMode];
 }

class ThemeStateInitial extends ThemeState {
   const ThemeStateInitial({required super.themeMode});
 }

class ThemeStateChanged extends ThemeState {
const ThemeStateChanged({required super.themeMode});
}

app_bloc.dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';

part 'app_event.dart';
part 'app_state.dart';

class AppBloc extends Bloc<AppEvent, AppState> {
   AppBloc() : super(AppStateInitial()) {
    on<AppEventReload>((event, emit) {
     emit(AppStateLoaded());
    });
   }
  }

main.dart

  void main() {
     runApp(
     MultiBlocProvider(
      providers: [
        BlocProvider(create: (context) => ThemeBloc()),
       BlocProvider(create: (context) => AppBloc()),
      ],
      child: MyApp(),
     ),
    );
   }

.

ThemeBloc → Handles light/dark theme switching. AppBloc → Manages general app state like user data and settings.

When ThemeBloc toggles the theme, AppBloc doesn’t react.

Theme change only affects the current page, other pages stay on the old theme.

When ThemeBloc is triggered, the theme only changes on this page.

class SettingsPage extends StatefulWidget {
   SettingsPage({super.key});

 @override
  State<SettingsPage> createState() => _SettingsPageState();
 }

 class _SettingsPageState extends State<SettingsPage> {
   @override
   Widget build(BuildContext context) {
    return BlocBuilder<AppBloc, AppState>(
     builder: (context, state) {
       final isDarkMode = (context.read<ThemeBloc>().state is ThemeStateChanged)
         ? (context.read<ThemeBloc>().state as ThemeStateChanged).themeMode == 
           ThemeMode.dark : false;

    return _buildToggleTile(
      Icons.dark_mode,
      'Karanlık Mod',
      isDarkMode,
      () {
        context.read<ThemeBloc>().add(ThemeEventToggle());
      },
      );
      },
     );
    }

I'm working with Flutter Bloc for state management. I have a ThemeBloc that toggles between light and dark modes, and I want to trigger AppBloc to perform an action whenever the theme changes. However, changes in ThemeBloc do not reflect in AppBloc.

theme_bloc.dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';

part 'theme_event.dart';
part 'theme_state.dart';

class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
  ThemeMode _themeMode = ThemeMode.system;

  ThemeBloc() : super(ThemeStateInitial(themeMode: ThemeMode.system)) {
    on<ThemeEventToggle>((event, emit) {
    _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
    emit(ThemeStateChanged(themeMode: _themeMode));
  });
 }
}

theme_event.dart

part of 'theme_bloc.dart';

sealed class ThemeEvent extends Equatable {
   const ThemeEvent();

  @override
  List<Object?> get props => [];
}

class ThemeEventToggle extends ThemeEvent {
  const ThemeEventToggle();
 }

theme_state.dart

part of 'theme_bloc.dart';

sealed class ThemeState extends Equatable {
   final ThemeMode themeMode;
   const ThemeState({required this.themeMode});

   @override
   List<Object> get props => [themeMode];
 }

class ThemeStateInitial extends ThemeState {
   const ThemeStateInitial({required super.themeMode});
 }

class ThemeStateChanged extends ThemeState {
const ThemeStateChanged({required super.themeMode});
}

app_bloc.dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';

part 'app_event.dart';
part 'app_state.dart';

class AppBloc extends Bloc<AppEvent, AppState> {
   AppBloc() : super(AppStateInitial()) {
    on<AppEventReload>((event, emit) {
     emit(AppStateLoaded());
    });
   }
  }

main.dart

  void main() {
     runApp(
     MultiBlocProvider(
      providers: [
        BlocProvider(create: (context) => ThemeBloc()),
       BlocProvider(create: (context) => AppBloc()),
      ],
      child: MyApp(),
     ),
    );
   }

.

ThemeBloc → Handles light/dark theme switching. AppBloc → Manages general app state like user data and settings.

When ThemeBloc toggles the theme, AppBloc doesn’t react.

Theme change only affects the current page, other pages stay on the old theme.

When ThemeBloc is triggered, the theme only changes on this page.

class SettingsPage extends StatefulWidget {
   SettingsPage({super.key});

 @override
  State<SettingsPage> createState() => _SettingsPageState();
 }

 class _SettingsPageState extends State<SettingsPage> {
   @override
   Widget build(BuildContext context) {
    return BlocBuilder<AppBloc, AppState>(
     builder: (context, state) {
       final isDarkMode = (context.read<ThemeBloc>().state is ThemeStateChanged)
         ? (context.read<ThemeBloc>().state as ThemeStateChanged).themeMode == 
           ThemeMode.dark : false;

    return _buildToggleTile(
      Icons.dark_mode,
      'Karanlık Mod',
      isDarkMode,
      () {
        context.read<ThemeBloc>().add(ThemeEventToggle());
      },
      );
      },
     );
    }
Share Improve this question asked Mar 21 at 18:07 yusufyusuf 235 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

If your app’s other pages aren’t updating, ensure that you’ve wrapped your app’s root widget with BlocBuilder, as shown below. This will automatically update your Material widget, thereby changing the theme for all screens.

Try taking reference from the below code :

class _SettingsPageState extends State<SettingsPage> {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ThemeBloc, ThemeState>(
      builder: (context, themeState) {
        final isDarkMode = themeState.themeMode == ThemeMode.dark;
        
        return _buildToggleTile(
          Icons.dark_mode,
          'Karanlık Mod',
          isDarkMode,
          () {
            context.read<ThemeBloc>().add(const ThemeEventToggle());
          },
        );
      },
    );
  }
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ThemeBloc, ThemeState>(
      builder: (context, themeState) {
        return MaterialApp(
          title: 'Your App',
          theme: ThemeData.light(), // Your light theme
          darkTheme: ThemeData.dark(), // Your dark theme
          themeMode: themeState.themeMode,
          home: HomePage(),
          // Other MaterialApp properties
        );
      },
    );
  }
}

本文标签: flutterHow to trigger another Bloc when one Bloc state changesStack Overflow