So I'm new to Bloc but I understand how it works from previously working on native android development, but what I'm trying to understand is should it be implemented to create something like a TextField. Now, keep in mind that I am trying to reuse this TextField multiple times and I want the bloc pattern to dynamically validate the input but should I implement it completely like handle the text inputted by the user?
what I've done is I've created a simple bloc pattern for the text field to handle the user input but it does not save the values from time to time it overwrites the previous value and the cursor keeps moving to the beginning of the text
import 'dart:math';
import 'package:competitionapp/data_model/events/formTextFieldEvent.dart';
import 'package:competitionapp/data_model/states/formTextFieldState.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
FormTextFieldBloc bloc = FormTextFieldBloc();
class FormTextFieldBloc extends Bloc<FormTextFieldEvent, FormTextFieldState> {
void onChanged(String value) {
if (value == null || value.isEmpty)
// todo change to handle errors
this.add(TextChangedEvent("error"));
else
this.add(TextChangedEvent(value));
}
@override
FormTextFieldState get initialState => FormTextFieldState.initState();
@override
Stream<FormTextFieldState> mapEventToState(FormTextFieldEvent event) async* {
if (event is TextChangedEvent) {
print("value received: ${event.eventText}");
yield FormTextFieldState(event.eventText);
}
}
}
import 'package:competitionapp/data_model/blocModels/formTextFieldBloc.dart';
import 'package:competitionapp/data_model/states/formTextFieldState.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class FormTextField extends StatelessWidget {
final TextEditingController _controller;
final String hint;
final IconData iconData;
final TextInputType inputType;
final int maxLines;
final int maxLength;
final EdgeInsetsGeometry padding;
final FormTextFieldBloc formTextFieldBloc;
FormTextField(this._controller, this.formTextFieldBloc,
{this.hint,
this.iconData,
this.inputType: TextInputType.text,
this.maxLines: 1,
this.maxLength,
this.padding: const EdgeInsets.fromLTRB(15, 5, 15, 5)});
@override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: BlocBuilder(
bloc: formTextFieldBloc,
builder: (context, FormTextFieldState state) {
if (state.text.isNotEmpty && state.text != null) {
_controller.text = state.text;
print("state text: ${state.text}");
}
return TextField(
onChanged: (value) {
print(value);
formTextFieldBloc.onChanged(_controller.text);
},
onEditingComplete: (){
print(_controller.text);
},
maxLength: maxLength ?? maxLength,
maxLines: maxLines,
keyboardType: inputType,
controller: _controller,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.transparent, width: 0)),
hintText: hint,
hintStyle:
Theme.of(context).textTheme.caption.copyWith(fontSize: 18),
filled: true,
fillColor: Theme.of(context).cardColor,
prefixIcon: Icon(
iconData,
size: 16,
color: Theme.of(context).hintColor,
),
),
);
},
),
);
}
}