J_Strauton
J_Strauton

Reputation: 2418

How to add bloc to a StatelessWidget screen

I have a screen like this:

class SettingsScreen extends StatefulWidget {
   @override
   _SettingsScreenState createState() => _SettingsScreenState();
}

class _SettingsScreenState() extends State<SettingsScreen> with TickerProviderStateMixin {
    ...
    listViews.add(
        UserView(

        );
    );
}

Then I have a bloc.

class UserBloc extends Bloc<UserEvent, UserState> {
    final UserRepo userRepo;
    UserBloc({@required this.userRepo}) : assert(userRepo != null);
}

How can I set my UserBloc to control the widget above? I am using this https://bloclibrary.dev/#/ for bloc.

Upvotes: 2

Views: 1667

Answers (3)

Sagar Acharya
Sagar Acharya

Reputation: 3767

From the code that you provided I have created a sample example where you can access the bloc with different approach

This is the Main UI file

import 'dart:math';

import 'package:flutter/material.dart';

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sample_app/bloc/home_bloc.dart';
import 'bloc/home_event.dart';
import 'bloc/home_state.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));

  // Approach 1
  // You can set the providers globally if you want the access evey where in the app.
  // So this is how you add it.

  // Below is the code you want to access a  single bloc globally
  // runApp(MaterialApp(
  //   home: BlocProvider(
  //       create: (blocContext) => HomeBloc(),
  //       child: MyApp(),
  //   ),
  // ));

  // Approach 2
  // But now lets say you want access 1 or more blocs globally then you use the Multi blocProvider
  // runApp(MaterialApp(
  //   home: MultiBlocProvider(
  //     providers: [
  //       BlocProvider<HomeBloc>(
  //         create: (BuildContext context) => HomeBloc(),
  //       ),
  //     ],
  //     child: MyApp(),
  //   ),
  // ));

  // Approach 3
  // This approach is you don't want the bloc to be accessable every where
  // It should only be accessed to under specific widgets
  // so you basically create the widget above that widget so that it can be accessable.
  // Check the  below example HomeBloc can only be access within the HomeListPage Widget
  // And if you provide it in the main then it is accessable globally.
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocProvider(
        create: (blocContext) => HomeBloc(),
        child: const HomeListPage(),
      ),
    );
  }
}

class HomeListPage extends StatefulWidget {
  const HomeListPage({Key? key}) : super(key: key);

  @override
  State<HomeListPage> createState() => _HomeListPageState();
}

class _HomeListPageState extends State<HomeListPage> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          BlocBuilder<HomeBloc, HomeState>(
            buildWhen: (previous, current) => current is HomeListState,
            builder: (context, state) {
              return state is HomeListState
                  ? ListView.builder(
                      shrinkWrap: true,
                      itemBuilder: (context, index) {
                        return Text(state.list[index]);
                      },
                      itemCount: state.list.length,
                    )
                  : const Text('List not displayed');
            },
          ),
          ElevatedButton(
              onPressed: () {
                context
                    .read<HomeBloc>()
                    .add(AddEvent(Random().nextInt(100).toString()));
              },
              child: const Text('Add item'))
        ],
      ),
    );
  }
}

This is the bloc File

import '../bloc/home_event.dart';
import '../bloc/home_state.dart';

import 'package:flutter_bloc/flutter_bloc.dart';

class HomeBloc extends Bloc<HomeEvent, HomeState> {
  List<String> list = [];

  HomeBloc() : super(HomeListState(['first Item in the list'])) {
    on<AddEvent>((event, emit) {
      // This is where the add event is triggered.
      list.add(event.item);

      emit(HomeListState(list));
    });
  }
}

This is the Event File

abstract class HomeEvent {}

class AddEvent extends HomeEvent {
  final String item;
  AddEvent(this.item);
}

This is the state File

abstract class HomeState {}

class InitialState extends HomeState {}

class AddState extends HomeState {}

class HomeListState extends HomeState {
  final List<String> list;

  HomeListState(this.list);
}

Upvotes: 0

Rajni Gujarati
Rajni Gujarati

Reputation: 2937

This way you can initialize bloc in a stateless widget. In my example, I'm using RxDart for my state management.

class HomePage extends StatelessWidget {
  final int id;
  final Bloc _bloc;

  HomePage({
    super.key,
    required this.id,
  }) : _bloc = Bloc(); 
}

Upvotes: 0

Abdelrahman Saed
Abdelrahman Saed

Reputation: 432

void main() {
runApp(App());
}
class App extends StatelessWidget {
 @override
Widget build(BuildContext context) {
  return  MaterialApp(
        title: 'Flutter Demo',
        home: BlocProvider(
          create: (_) => UserBloc(),
          child: SettingsScreen(),
        ),
      );;
  }
}

class SettingsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return Scaffold(
  body: BlocBuilder< UserBloc, UserState>(
    builder: (user, userState) {
      return Text(
          'new event and new state',
        ),
      );
    },
  )
}

Upvotes: 1

Related Questions