chat_bubbles icon indicating copy to clipboard operation
chat_bubbles copied to clipboard

TextController value is lost on state change

Open Samleet opened this issue 2 years ago • 8 comments

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 = ''; } }, ), ), ], ), ), ], ), ), ); } }

Samleet avatar Sep 04 '22 22:09 Samleet

chat_bubble_message_bar_issue

Samleet avatar Sep 04 '22 22:09 Samleet

@prahack i've longed drop this issue and solution. you didn't give any reason. this package needs update.

Samleet avatar Mar 08 '23 12:03 Samleet

@Samleet Sorry for the late reply. I am working on this. Thank you very much for informing me.

prahack avatar Mar 18 '23 07:03 prahack

please add a way to reproduce this error

prahack avatar Mar 18 '23 10:03 prahack

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✌️

JohnF17 avatar Aug 18 '23 23:08 JohnF17

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

kandelin16 avatar Apr 04 '24 21:04 kandelin16

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.

Samleet avatar Apr 05 '24 07:04 Samleet

When are we gonna get a fix and release ?

Waxo avatar Sep 05 '24 15:09 Waxo