chat_bubbles
chat_bubbles copied to clipboard
TextController value is lost on state change
Hi, i found the following issues while using plugin. The value / state of keyboard entry is lost when any of the following event is fired. (keyboard close, keyboard mode toggle).
This is as a result of using a "Stateless" widget on the "MessageBar" class. I had to convert the class to "Stateful" widget to override this behaviour.
[ message_bar.dart ]
import 'package:flutter/material.dart';
///Normal Message bar with more actions
///
/// following attributes can be modified
///
///
/// # BOOLEANS
/// [replying] is additional reply widget top of the message bar
///
/// # STRINGS
/// [replyingTo] is a string to tag the replying message
///
/// # WIDGETS
/// [actions] are the additional leading action buttons like camera
/// and file select
///
/// # COLORS
/// [replyWidgetColor] is reply widget color
/// [replyIconColor] is the reply icon color on the left side of reply widget
/// [replyCloseColor] is the close icon color on the right side of the reply
/// widget
/// [messageBarColor] is the color of the message bar
/// [sendButtonColor] is the color of the send button
///
/// # METHODS
/// [onTextChanged] is function which triggers after text every text change
/// [onSend] is send button action
/// [onTapCloseReply] is close button action of the close button on the
/// reply widget usually change [replying] attribute to false
class MessageBar extends StatefulWidget { final bool replying; final String replyingTo; final List<Widget> actions; final Color replyWidgetColor; final Color replyIconColor; final Color replyCloseColor; final Color messageBarColor; final Color sendButtonColor; final void Function(String)? onTextChanged; final void Function(String)? onSend; final void Function()? onTapCloseReply;
/// [MessageBar] constructor /// /// MessageBar({ this.replying = false, this.replyingTo = "", this.actions = const [], this.replyWidgetColor = const Color(0xffF4F4F5), this.replyIconColor = Colors.blue, this.replyCloseColor = Colors.black12, this.messageBarColor = const Color(0xffF4F4F5), this.sendButtonColor = Colors.blue, this.onTextChanged, this.onSend, this.onTapCloseReply, });
@override State<MessageBar> createState() => _MessageBarState(); }
class _MessageBarState extends State<MessageBar> { final TextEditingController _textController = TextEditingController(); /// [MessageBar] builder method /// @override Widget build(BuildContext context) { return Align( alignment: Alignment.bottomCenter, child: Container( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ widget.replying ? Container( color: widget.replyWidgetColor, padding: const EdgeInsets.symmetric( vertical: 8, horizontal: 16, ), child: Row( children: [ Icon( Icons.reply, color: widget.replyIconColor, size: 24, ), Expanded( child: Container( child: Text( 'Re : ' + widget.replyingTo, overflow: TextOverflow.ellipsis, ), ), ), InkWell( onTap: widget.onTapCloseReply, child: Icon( Icons.close, color: widget.replyCloseColor, size: 24, ), ), ], )) : Container(), widget.replying ? Container( height: 1, color: Colors.grey.shade300, ) : Container(), Container( color: widget.messageBarColor, padding: const EdgeInsets.symmetric( vertical: 8, horizontal: 16, ), child: Row( children: <Widget>[ ...widget.actions, Expanded( child: Container( child: TextField( controller: _textController, keyboardType: TextInputType.multiline, textCapitalization: TextCapitalization.sentences, minLines: 1, maxLines: 3, onChanged: widget.onTextChanged, decoration: InputDecoration( hintText: "Type your message here", hintMaxLines: 1, contentPadding: const EdgeInsets.symmetric( horizontal: 8.0, vertical: 10), hintStyle: TextStyle( fontSize: 16, ), fillColor: Colors.white, filled: true, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), borderSide: const BorderSide( color: Colors.white, width: 0.2, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), borderSide: const BorderSide( color: Colors.black26, width: 0.2, ), ), ), ), ), ), Padding( padding: const EdgeInsets.only(left: 16), child: InkWell( child: Icon( Icons.send, color: widget.sendButtonColor, size: 24, ), onTap: () { if (_textController.text.trim() != '') { if (widget.onSend != null) { widget.onSend!(_textController.text.trim()); } _textController.text = ''; } }, ), ), ], ), ), ], ), ), ); } }
@prahack i've longed drop this issue and solution. you didn't give any reason. this package needs update.
@Samleet Sorry for the late reply. I am working on this. Thank you very much for informing me.
please add a way to reproduce this error
Hey @Samleet, bit too late to the party but the issue is that your controller is initialized on class level, a simple edit like the one below should fix your issue.
class _MessageBarState extends State<MessageBar> {
late TextEditingController _textController;
@override
void initState(){
super.initState();
_textController = TextEditingController();
}
@override
void dispose(){
// NEVER FORGET TO DISPOSE ANY OF YOUR CONTROLLERS
_textController.dispose();
super.dispose();
}
// THE REST OF YOUR CODE WITHIN THE STATE ....
}
This isn't the package's issue but rather an initialization issue Dev-Tip: as i mentioned in the comments never forget to dispose controllers, else they might cause MEMORY LEAKS! Cheers✌️
Just came to mention I had a similar issue with the library. My messaging app listens to a stream, and when a new message is received the value typed into the messagebar would be lost. I solved it by creating my own version of messagebar that is stateful.
I went ahead and opened a PR for this change if you want to take a look https://github.com/prahack/chat_bubbles/pull/45
Just came to mention I had a similar issue with the library. My messaging app listens to a stream, and when a new message is received the value typed into the messagebar would be lost. I solved it by creating my own version of messagebar that is stateful.
I went ahead and opened a PR for this change if you want to take a look #45
Yes, you're right. That was what I ended up implementing when I found the issue. It'd be great if the PR was merge if that isn't currently fixed yet.
When are we gonna get a fix and release ?