Flutter BlocBuilder doesn't update my List of Inputs

Viewed 14

I'm using Flutter Bloc to keep track of state changes in my PIN and Fingerprint Authentication.

Currently i have the problem that my List of current Pin Inputs just get updated for the first item in the List. All the following inputs don't update the UI, but the List keeps on growing.

My Authentication_Bloc:

abstract class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationPinState> {
  AuthenticationBloc()
      : super(AuthenticationPinState(
            pinNumbers: const [], pinStatus: AuthenticationPINStatus.enter));
}

class AuthenticationPinBloc extends AuthenticationBloc {
  List<int> pinNumbers = [];
  AuthenticationPinBloc() : super() {
    on<AuthenticationPinAddEvent>((event, emit) async {
      try {
        pinNumbers.add(event.pinNumber);
        if (pinNumbers.length < 6) {
          emit(state.copyWith(
              pinNumbers: pinNumbers,
              pinStatus: AuthenticationPINStatus.enter));
        } else if (pinNumbers.length == 6) {
          emit(state.copyWith(
              pinNumbers: pinNumbers,
              pinStatus: AuthenticationPINStatus.equals));
        } else {
          emit(state.copyWith(
              pinNumbers: pinNumbers,
              pinStatus: AuthenticationPINStatus.unequals));
          await Future.delayed(
              const Duration(seconds: 2),
              () => emit(AuthenticationPinState(
                  pinNumbers: pinNumbers,
                  pinStatus: AuthenticationPINStatus.enter)));
        }
      } catch (e) {}
    });
    on<AuthenticationPinEraseEvent>((event, emit) async {});
    on<AuthenticationFingerprintEvent>((event, emit) {});
  }
}

My Authentication_State:

enum AuthenticationPINStatus { enter, equals, unequals }

abstract class AuthenticationState extends Equatable {
  @override
  List<Object?> get props => [];
}

// Waiting to see if the user is authenticated
class AuthenticationUninitialized extends AuthenticationState {}

// Sucessfully authenticated
class AuthenticationAuthenticated extends AuthenticationState {}

// Not authenticated
class AuthenticationUnauthenticated extends AuthenticationState {}

class AuthenticationLoading extends AuthenticationState {}

class AuthenticationPinState extends AuthenticationState {
  final List<int> pinNumbers;
  final AuthenticationPINStatus pinStatus;
  AuthenticationPinState({required this.pinNumbers, required this.pinStatus});

  AuthenticationPinState copyWith(
      {required AuthenticationPINStatus pinStatus,
      required List<int> pinNumbers}) {
    return AuthenticationPinState(pinNumbers: pinNumbers, pinStatus: pinStatus);
  }

  int getPINCount() {
    return pinNumbers.length;
  }

  @override
  List<Object?> get props => [List.from(pinNumbers), pinStatus];
}

My Authentication_Event:

abstract class AuthenticationEvent extends Equatable {
  const AuthenticationEvent([List props = const []]) : super();
}

abstract class AuthenticationPinEvent extends AuthenticationEvent {
  final int pinNumber;

  const AuthenticationPinEvent({required this.pinNumber});
  @override
  List<Object?> get props => [pinNumber];
}

class AuthenticationPinAddEvent extends AuthenticationPinEvent {
  const AuthenticationPinAddEvent({required int pinNumber})
      : super(pinNumber: pinNumber);

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

class AuthenticationPinEraseEvent extends AuthenticationPinEvent {
  const AuthenticationPinEraseEvent() : super(pinNumber: -1);

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

class AuthenticationFingerprintEvent extends AuthenticationEvent {
  const AuthenticationFingerprintEvent();

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

My Code calling the Bloc:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: BlocProvider(
        create: (context) => AuthenticationPinBloc(),
        child: BlocListener<AuthenticationPinBloc, AuthenticationPinState>(
          listener: (context, state) {
            if (state.pinStatus == AuthenticationPINStatus.equals) {
              // Validate PIN
            } else if (state.pinStatus == AuthenticationPINStatus.unequals) {
              // Retry Logic
            }
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              const SizedBox(
                height: 120,
              ),
              Flexible(
                flex: 2,
                child: Text(authenticationByPINCode,
                    style: Theme.of(context)
                        .textTheme
                        .titleLarge
                        ?.merge(const TextStyle(color: Colors.blueGrey))),
              ),
              BlocBuilder<AuthenticationPinBloc, AuthenticationPinState>(
                buildWhen: (previous, current) {
                  return previous.pinNumbers != current.pinNumbers;
                },
                builder: (context, state) {
                  return BlocProvider<AuthenticationPinBloc>.value(
                    value: context.read<AuthenticationPinBloc>(),
                    child: Flexible(
                        flex: 1,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: List.generate(6, (index) {
                            return PinSphere(
                                input: index < state.getPINCount());
                          }),
                        )),
                  );
                },
              ),
              const SizedBox(
                height: 80,
              ),
              const Flexible(flex: 3, child: Numpad())
            ],
          ),
        ),
      )),
    );
  }
0 Answers
Related