skip to Main Content

here is my main screen ui page
to display notes in listview builder
here my issue is when i am trying to select an item to favourites (there is an icon for favourites) , it will select all list items to favourites , iam new to flutter bloc , i think here i am done something wrong on clicking the event, please help.

class MyHomePage extends StatelessWidget {
  MyHomePage({super.key,required this.title});
  final String title;
  List<NoteListModel>noteList = [];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(title),
      ),
      body: Center(
        child: BlocBuilder<NotesBloc,NotesState>(
            builder: (context, state) {
              if(state is NotesInitial)
              {
                return const Text('no text');
              }else if(state is NotesAddedState || state is NoteDeletedState
              || state is NotesFavouritesState)
              {
                return ListView.builder(
                    itemCount: state.noteList.length,
                    itemBuilder:(context,index){
                      return Container(
                        decoration: BoxDecoration(
                          borderRadius: const BorderRadius.all(Radius.circular(15.0)),
                          border: Border.all(
                            width: 1.0,
                          ),
                        ),
                        child: ListTile(
                          visualDensity: VisualDensity.standard,
                          leading:  Text(state.noteList[index].noteTitle.toString()),
                          subtitle:  Text(state.noteList[index].noteDetail.toString()),
                          trailing: SizedBox(
                            width:MediaQuery.of(context).size.width/3,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.end,
                              children: [
                                IconButton(
                                  icon: state.favourites ?const Icon(Icons.favorite,color: Colors.red,):
                                  const Icon(Icons.favorite_border),
                                  onPressed: () {
                                    if(state.favourites)
                                      {
                                        context.read<NotesBloc>().add(NoteFavouritesClicked(favourites: false,
                                            index: index));
                                      }else{
                                      context.read<NotesBloc>().add(NoteFavouritesClicked
                                        (favourites: true, index: index,));
                                    }
                                  },),
                                IconButton(
                                  icon: const Icon(Icons.delete),
                                  onPressed: () {
                                    print('deleted index:${index}');
                                    BlocProvider.of<NotesBloc>(context).add(
                                        NoteDeleteEvent(state.noteList[index]));
                                  },),

                              ],
                            ),
                          ),
                        ),
                      );
                    });
              }
              return const Center(child: Text('error'),);
            }),
      ),
      floatingActionButton:  Padding(
        padding: const EdgeInsets.all(8.0),
        child: FloatingActionButton.extended(
          onPressed:(){
            Popup.showDialogPopup(context);
          },
          tooltip: 'Increment',
          label: const Row(
            children: [
              Text('Add Note'),
              SizedBox(width: 10,),
              Icon(Icons.add)
            ],
          ),
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

here is my bloc class

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import '../model/note_list_model.dart';
part 'notes_event.dart';
part 'notes_state.dart';

class NotesBloc extends Bloc<NotesEvent,NotesState> {
  List <NoteListModel>noteList = [];
  NotesBloc() : super(NotesInitial(noteList: [])) {
    on<NoteEvent>((event, emit) {
      noteList.add(event.note);
      emit(NotesAddedState(noteList:noteList));
    });

    on<NoteFavouritesClicked>((event, emit){
      if(event.index >= 0 && event.index < noteList.length)
        {
          noteList[event.index].favourites = event.favourites;
        }else{
        print('index out of bound');
      }
      emit(NotesFavouritesState(favourites: event.favourites, noteList:noteList));
    });

    on<NoteDeleteEvent>((event,emit){
       noteList.remove(event.noteDelete);
      emit(NoteDeletedState(noteList: noteList));
    });

    on<NoteUpdateEvent>((event,emit){
      noteList.add(event.updateNotes);
      emit(NoteUpdatedState(noteList: noteList));
    });
  }
}

here is my event class
add, delete , favourites.

part of 'notes_bloc.dart';

abstract class NotesEvent {
  const NotesEvent();
}

class NoteEvent  extends NotesEvent{
  NoteListModel note;
  NoteEvent(this.note);
}

class NoteDeleteEvent  extends NotesEvent{
  NoteListModel noteDelete;
  NoteDeleteEvent(this.noteDelete);
}
class NoteUpdateEvent extends NotesEvent{
  NoteListModel updateNotes;
  NoteUpdateEvent(this.updateNotes);
}

class NoteFavouritesClicked extends NotesEvent{
  int index;
  bool favourites;
  NoteFavouritesClicked({required this.favourites,required this.index});
}

here is my state class
for add note , delete note and favourites.

part of 'notes_bloc.dart';

  class NotesState {
  List<NoteListModel> noteList;
  bool favourites;
  NotesState({required this.noteList,this.favourites = false});

  @override
  List<Object?> get props => [noteList,favourites];
}
class NotesAddedState extends NotesState{
   List<NoteListModel> noteList;
  NotesAddedState({required this.noteList}) : super(noteList: noteList);
  @override
  List<Object?> get props => [noteList];
}
class NotesFavouritesState extends NotesState{
    bool favourites;
    NotesFavouritesState({this.favourites= false, required List<NoteListModel> noteList}) :
          super(noteList: noteList);
}
class NoteDeletedState extends NotesState{
  List<NoteListModel> noteList;
  NoteDeletedState({required this.noteList}) : super(noteList: noteList);
  @override
  List<Object?> get props => [noteList];
}
class NoteUpdatedState extends NotesState{
  List<NoteListModel> noteList;
  NoteUpdatedState({required this.noteList}): super(noteList: noteList);
  @override
  List<Object?> get props => [noteList];
}
class NotesInitial extends NotesState {
   NotesInitial({required super.noteList});
  @override
  List<Object> get props => [];
}

2

Answers


  1. As far i’ve gone through your code, i think the issue is occurring cause your NotesBloc class member noteList is non-static. So every time the new instance is being created.

    So you make that list static as:

    static List<NoteListModel> noteList = [];
    

    And then you need to give it the values initially, like

    NotesBloc.noteList = data; ;  /// your [DataList]
    

    and you can use in your listView. as everyone sharing the same instance you no need to the emit the list with the states. you can just emit a state with no data and change will be reflect in the UI.

    Login or Signup to reply.
  2. From the code that i have seen you just need the following change in the UI every thing will work as expected.

    IconButton(
                                  icon: state.noteList[index].favourites == true
                                      ? const Icon(
                                          Icons.favorite,
                                          color: Colors.red,
                                        )
                                      : const Icon(Icons.favorite_border),
                                  onPressed: () {
                                    if (state.favourites) {
                                      context.read<NotesBloc>().add(
                                          NoteFavouritesClicked(
                                              favourites: false, index: index));
                                    } else {
                                      context
                                          .read<NotesBloc>()
                                          .add(NoteFavouritesClicked(
                                            favourites: true,
                                            index: index,
                                          ));
                                    }
                                  },
                                ),
    

    This above code is for the faviorites button. please check the icon differnce.

    I have added the detailed answer if you want to run the app.

    UI File

    import 'package:flutter/material.dart';
    import 'bloc/todo_state.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    import 'bloc/todo_bloc.dart';
    import 'bloc/todo_event.dart';
    
    void main() {
      runApp(MaterialApp(
        home: BlocProvider(
          create: (_) => NotesBloc(),
          child: const MyApp(),
        ),
      ));
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('ToDo App'),
          ),
          body: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      List<NoteListModel> noteList = [];
    
      TextEditingController noteTitleController = TextEditingController();
    
      TextEditingController noteDetailController = TextEditingController();
    
      Future<void> _showAlertDialog() async {
        return showDialog<void>(
          context: context,
          barrierDismissible: false, // user must tap button!
          builder: (BuildContext dialogContext) {
            return AlertDialog(
              // <-- SEE HERE
              title: const Text(' Create new Note'),
              content: SingleChildScrollView(
                child: ListBody(
                  children: <Widget>[
                    TextField(
                      controller: noteTitleController,
                    ),
                    TextField(
                      controller: noteDetailController,
                    )
                  ],
                ),
              ),
              actions: <Widget>[
                TextButton(
                  child: const Text('No'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
                TextButton(
                  child: const Text('Add note'),
                  onPressed: () {
                    context.read<NotesBloc>().add(NoteEvent(NoteListModel(
                        noteTitleController.text, noteDetailController.text)));
    
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          },
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: Text('asdfasdf'),
          ),
          body: Center(
            child: BlocBuilder<NotesBloc, NotesState>(builder: (context, state) {
              print('This is the state ${state}');
              if (state is NotesInitial) {
                return const Text('no text');
              } else if (state is NotesAddedState ||
                  state is NoteDeletedState ||
                  state is NotesFavouritesState) {
                return ListView.builder(
                    itemCount: state.noteList.length,
                    itemBuilder: (context, index) {
                      return Container(
                        decoration: BoxDecoration(
                          borderRadius:
                              const BorderRadius.all(Radius.circular(15.0)),
                          border: Border.all(
                            width: 1.0,
                          ),
                        ),
                        child: ListTile(
                          visualDensity: VisualDensity.standard,
                          leading: Text(state.noteList[index].noteTitle.toString()),
                          subtitle:
                              Text(state.noteList[index].noteDetail.toString()),
                          trailing: SizedBox(
                            width: MediaQuery.of(context).size.width / 3,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.end,
                              children: [
                                IconButton(
                                  icon: state.noteList[index].favourites == true
                                      ? const Icon(
                                          Icons.favorite,
                                          color: Colors.red,
                                        )
                                      : const Icon(Icons.favorite_border),
                                  onPressed: () {
                                    if (state.favourites) {
                                      context.read<NotesBloc>().add(
                                          NoteFavouritesClicked(
                                              favourites: false, index: index));
                                    } else {
                                      context
                                          .read<NotesBloc>()
                                          .add(NoteFavouritesClicked(
                                            favourites: true,
                                            index: index,
                                          ));
                                    }
                                  },
                                ),
                                IconButton(
                                  icon: const Icon(Icons.delete),
                                  onPressed: () {
                                    print('deleted index:${index}');
                                    BlocProvider.of<NotesBloc>(context).add(
                                        NoteDeleteEvent(state.noteList[index]));
                                  },
                                ),
                              ],
                            ),
                          ),
                        ),
                      );
                    });
              }
              return const Center(
                child: Text('error'),
              );
            }),
          ),
          floatingActionButton: Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton.extended(
              onPressed: () async {
                await _showAlertDialog();
              },
              tooltip: 'Increment',
              label: const Row(
                children: [
                  Text('Add Note'),
                  SizedBox(
                    width: 10,
                  ),
                  Icon(Icons.add)
                ],
              ),
            ),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    

    Created a bloc folder and added bloc event and state files in it please check I have made few changes.

    Bloc file

    import 'package:bloc/bloc.dart';
    import '../bloc/todo_event.dart';
    import '../bloc/todo_state.dart';
    
    class NotesBloc extends Bloc<NotesEvent, NotesState> {
      List<NoteListModel> noteList = [];
      NotesBloc() : super(NotesInitial(noteList: [])) {
        on<NoteEvent>((event, emit) {
          noteList.add(event.note);
          emit(NotesAddedState(noteList: noteList));
        });
    
        on<NoteFavouritesClicked>((event, emit) {
          if (event.index >= 0 && event.index < noteList.length) {
            noteList[event.index].favourites = event.favourites;
            noteList.forEach((element) {
              print("This is the list data :${element.favourites}");
              print('${element.noteTitle}');
            });
          } else {
            print('index out of bound');
          }
          emit(NotesFavouritesState(
              favourites: event.favourites, noteList: noteList));
        });
    
        on<NoteDeleteEvent>((event, emit) {
          noteList.remove(event.noteDelete);
          emit(NoteDeletedState(noteList: noteList));
        });
    
        on<NoteUpdateEvent>((event, emit) {
          noteList.add(event.updateNotes);
          emit(NoteUpdatedState(noteList: noteList));
        });
        emit(NotesInitial(noteList: []));
      }
    }
    
    

    Event file

    import '../bloc/todo_state.dart';
    
    abstract class NotesEvent {
      const NotesEvent();
    }
    
    class NoteEvent extends NotesEvent {
      NoteListModel note;
      NoteEvent(this.note);
    }
    
    class NoteDeleteEvent extends NotesEvent {
      NoteListModel noteDelete;
      NoteDeleteEvent(this.noteDelete);
    }
    
    class NoteUpdateEvent extends NotesEvent {
      NoteListModel updateNotes;
      NoteUpdateEvent(this.updateNotes);
    }
    
    class NoteFavouritesClicked extends NotesEvent {
      int index;
      bool favourites;
      NoteFavouritesClicked({required this.favourites, required this.index});
    }
    
    

    State file

    class NotesState {
      List<NoteListModel> noteList;
      bool favourites;
      NotesState({required this.noteList, this.favourites = false});
    
      @override
      List<Object?> get props => [noteList, favourites];
    }
    
    class NotesAddedState extends NotesState {
      List<NoteListModel> noteList;
      NotesAddedState({required this.noteList}) : super(noteList: noteList);
      @override
      List<Object?> get props => [noteList];
    }
    
    class NotesFavouritesState extends NotesState {
      bool favourites;
      NotesFavouritesState(
          {this.favourites = false, required List<NoteListModel> noteList})
          : super(noteList: noteList);
    }
    
    class NoteDeletedState extends NotesState {
      List<NoteListModel> noteList;
      NoteDeletedState({required this.noteList}) : super(noteList: noteList);
      @override
      List<Object?> get props => [noteList];
    }
    
    class NoteUpdatedState extends NotesState {
      List<NoteListModel> noteList;
      NoteUpdatedState({required this.noteList}) : super(noteList: noteList);
      @override
      List<Object?> get props => [noteList];
    }
    
    class NotesInitial extends NotesState {
      NotesInitial({required super.noteList});
      @override
      List<Object> get props => [];
    }
    
    class NoteListModel {
      String noteTitle;
    
      bool? favourites = false;
      String noteDetail;
    
      NoteListModel(this.noteTitle, this.noteDetail, {this.favourites});
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search