How to Dynamically change Icon Button to String or Emoji - flutter

So I am Making a Todo App, which has a work of Emoji in it.
I am Currently Using PubPackage, emoji_picker: ^0.1.0 For its help i can open and Close Emoji Keyboard Easily.
BTW, the Code You can see, is a Code of Opening EmojiKeyboard.
Widget emojiSelect() {
return EmojiPicker(
numRecommended: 25,
recommendKeywords: ["sing", "coding"],
columns: 7,
rows: 3,
onEmojiSelected: (emoji, catergory) {
print(emoji);
});
}
Here, when I am Pressing the button, A Emoji Keyboard is Opening Perfectly,
And I am pretty happy with it.
Now, I want to Make something, like if we Click on one of the Emoji which is resting inside the Emoji_keyboard then the Icon as you can see(in the below image)
Changes to Emoji, which User Clicked through KeyBoard.
Is there a Way, the Icon to change itself to "Emoji" that the user Clicked and if we long-press the same Button we can again Edit the Emoji to choose another, as per our choice?
The Whole Code, Pretty much looks like this,
return Wrap(
children: [
WillPopScope(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Wrap(
//height: MediaQuery.of(context).size.height / 4.8,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
TextFormField(
focusNode: focusNode,
autofocus: false,
autocorrect: true,
decoration: InputDecoration(
hoverColor: Colors.amber,
border: InputBorder.none,
prefixIcon: Icon(CarbonIcons.pen_fountain),
hintText: "What toodo?",
hintStyle: TextStyle(
color: Colors.black54,
fontWeight: FontWeight.w200),
contentPadding: EdgeInsets.all(20.0),
),
),
// TextFormField(
// autocorrect: true,
// decoration: InputDecoration(
// hoverColor: Colors.amber,
// border: InputBorder.none,
// prefixIcon: Icon(CarbonIcons.pen),
// hintText: "Description (optional)",
// hintStyle: TextStyle(
// color: Colors.black54,
// fontWeight: FontWeight.w200),
// contentPadding: EdgeInsets.all(20.0),
// ),
// ),
Row(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
icon: Icon(CarbonIcons.notification),
onPressed: () async {
final TimeOfDay newTime =
await showTimePicker(
context: context,
initialTime:
TimeOfDay(hour: 7, minute: 15),
);
},
color: Colors.black54,
),
IconButton(
icon: Icon(CarbonIcons.face_add),
onPressed: () {
setState(() {
focusNode.unfocus();
focusNode.canRequestFocus = false;
showEmojiKeyboard = !showEmojiKeyboard;
});
},
color: Colors.black54,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FlatButton.icon(
onPressed: () {},
color: Colors.blue,
icon: Icon(
CarbonIcons.add,
color: Colors.white,
),
label: Text(
"Add Todo",
style: TextStyle(color: Colors.white),
))
],
),
Divider(),
],
)
],
),
],
),
showEmojiKeyboard ? emojiSelect() : Container(),
],
),
onWillPop: () {
if (showEmojiKeyboard) {
setState(() {
showEmojiKeyboard = false;
});
} else {
Navigator.pop(context);
}
return Future.value(false);
},
),
],
);

Seems like the selected emoji type is String so basically on selection of emoji you need to display a Text Widget in place of the icon.
String selectedEmoji;
Widget emojiSelect() {
return EmojiPicker(
numRecommended: 25,
recommendKeywords: ["sing", "coding"],
columns: 7,
rows: 3,
onEmojiSelected: (emoji, catergory) {
setState((){
selectedEmoji = emoji;
})
});
}
And the place where you show the icon has to be replaced with the Text() widget conditionally
IconButton(
icon: selectedEmoji==null? Icon(CarbonIcons.face_add):Text(selectedEmoji),
onPressed: () {
setState(() {
focusNode.unfocus();
focusNode.canRequestFocus = false;
showEmojiKeyboard = !showEmojiKeyboard;
});
},
color: Colors.black54,
)

Related

Space bar key doesn't work on textfields ( Flutter Web )

In our application, SOMETIMES space input doesn't work in textFields (f.e. adding a new message in a chat), but after refreshing the page it works again. This situation is causing unstable environment for our users and thus a lot of complaints. Is there any official documentation, or solution by flutter for this "sometimes space button cannot be used" problem. What we notices that, when this problem occurs, fonts are different than it supposed to be, like it's not loaded. It is not browser specific because problem occurs at Chrome & Edge.
The real problem is that the bug is not easy to detect because it happens only few times so i don't know how to detect and solve it.
In particular i noted that it happens only in production ( i never spotted it during development) .
Flutter doctor:
This is an example widget that have the bug
Widget build(BuildContext context) {
return CustomAlertDialog(
title: const Text(
"Aggiungi un messaggio",
style: TextStyle(fontSize: 16),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Annulla",
style: TextStyle(color: Colors.grey.shade700),
)),
TextButton(
onPressed: () {
},
child: const Text("Invia"))
],
content: Container(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: const EdgeInsets.only(top: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
border: Border.all(
color: Colors.green,
width: 2,
),
),
width: 800,
child: TextField(
minLines: 8,
maxLines: 8,
autofocus: false,
controller: _chatController,
//keyboardType: TextInputType.multiline,
onChanged: (text) {
setState(() {
textValue = text;
});
},
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(8),
hintText: "Scrivi qui il tuo messaggio",
border: InputBorder.none,
),
),
),
SizedBox(
height: 10,
),
CheckboxListTile(
value: _hiddenMessage,
onChanged: (value) {
setState(() {
_hiddenMessage = value!;
});
},
title: const Text("Nascondi"),
)
],
),
),
));
}
CustomAlertDialog:
class _CustomAlertDialogState extends State<CustomAlertDialog> {
#override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: widget.insetPadding ??
EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
title: widget.title ??
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Icon(
Icons.cancel,
color: Colors.red,
size: 30,
),
SizedBox(width: 5),
Text('Errore'),
],
),
elevation: widget.elevation ?? 24.0,
actions: widget.actions ??
[
TextButton(
child: const Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
content: widget.content ??
const Text(
"Errore di connessione al server",
style: TextStyle(fontSize: 20),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
);
}
}
Thank you for the help!
Widget build(BuildContext context) {
return MaterialApp(
shortcuts: {
LogicalKeySet(LogicalKeyboardKey.space): ActivateIntent(),
},
title: 'title of your app',
//....
);
}

How to do ElevatedButton disabled?

I want the button to be inactive until 10 characters are entered in the field. When 10 characters were entered, the button was active. And when it is inactive it is gray, and when it is active it is blue. How can I do that?
Here is the input code with the button:
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Padding(
padding: EdgeInsets.fromLTRB(
20, MediaQuery.of(context).size.height * 0, 20, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
onChanged: (String value) {
setState(() {
_showIcon = value.isNotEmpty;
});
},
controller: _inputController,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 2.0),
),
hintText: "(1201) 565-0123 ",
hintStyle: TextStyle(color: Colors.grey, fontSize: 15),
helperText: 'Enter your phone number',
helperStyle: TextStyle(color: Colors.grey, fontSize: 15),
suffixIcon: _showIcon
? IconButton(
onPressed: () {
setState(() {
_inputController.clear();
_showIcon = false;
});
},
icon: const Icon(Icons.close, color: Colors.grey),
) : null,
),
keyboardType: TextInputType.number,
inputFormatters: [maskFormatter],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
},
child: const Icon(Icons.arrow_forward_rounded, size: 25),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(15)
)
),
],
)
],
),
),
),
);
}
}
You can call setState(() {}); on onChanged to update the UI, or add listener on _inputController.
ElevatedButton(
onPressed:
_inputController.text.length < 10 ? null : () {},
...
Passing onPressed:null will provide disable state.
Updating UI can be done
TextField(
onChanged: (String value) {
setState(() {});
},
....)
Or
late final TextEditingController _inputController;
#override
void initState() {
super.initState();
_inputController = TextEditingController()
..addListener(() {
setState(() {});
});
}
Use a variable like isEnabled and passing null to the onPress function will disable the button.
bool isEnabled=false;
void callbackfunction(){
// add your logic here.
}
....
....
TextField(
onChanged: (String value) {
if (value.length == 10){
setState(()=> isEnabled = true;)
}
else{
isEnabled=false;
}
setState(() {
_showIcon = value.isNotEmpty;
});
},
....
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: isEnabled ? callbackfunction : null,
child: const Icon(Icons.arrow_forward_rounded, size: 25),
style: ElevatedButton.styleFrom(
color: isEnabled ? Colors.blue : Colors.grey,
shape: CircleBorder(),
padding: EdgeInsets.all(15)
)
),
],
)
],
),
P.S Please check the syntax I have just provided you the concept.

Using Visibility Widget in Flutter to toggle widgets display

I have a Column widget I'd only like to make visible when a user taps on the add new button. I am using the Visibility widget Flutter provides and I am using setState() to change the visible property in the Visibility widget class. It doesn't work.
What could I be overlooking? Find my code snippet below:
bool _addNewTax = false;
FlatButton.icon(
color: kBgCircleColour,
padding: EdgeInsets.all(15.0),
icon: Icon(
FontAwesomeIcons.plusSquare,
color: kThemeStyleButtonFillColour,
),
onPressed: () {
setState(() {
_addNewTax = true;
});
Visibility(
visible: _addNewTax,
child: _buildTaxInputFields(),
);
},
label: Text(
'Add new tax',
style: kRegularTextStyle,
),
);
My _buildTaxInputFields function as below:
_buildTaxInputFields() {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
initialValue: inputValue,
textAlign: TextAlign.left,
onSaved: () {},
decoration: kTextFieldDecoration.copyWith(hintText: 'tax name e.g. VAT, service charge, etc'),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
initialValue: inputValue,
textAlign: TextAlign.left,
onSaved: () {},
decoration: kTextFieldDecoration.copyWith(hintText: 'tax percentage e.g. 20, 19.5'),
),
Row(
children: <Widget>[
Expanded(
flex: 1,
child: RadioListTile(
title: Text('I\'ll bear it '),
value: TaxBearer.merchant,
groupValue: _taxBearer,
onChanged: (TaxBearer value) {
setState(() {
_taxBearer = value;
});
},
),
),
Expanded(
flex: 1,
child: RadioListTile(
title: Text('Push to customer'),
value: TaxBearer.customer,
groupValue: _taxBearer,
onChanged: (TaxBearer value) {
setState(() {
_taxBearer = value;
});
}),
),
],
),
],
);
}
Your visibility widget will never be rendered because you're generating it in the onPressed method of a button.
You could use a column to generate it below the button like this:
bool _addNewTax = false;
Column(
children: [
FlatButton.icon(
color: kBgCircleColour,
padding: EdgeInsets.all(15.0),
icon: Icon(
FontAwesomeIcons.plusSquare,
color: kThemeStyleButtonFillColour,
),
onPressed: () {
setState(() {
_addNewTax = true;
});
},
label: Text(
'Add new tax',
style: kRegularTextStyle,
),
),
Visibility(
visible: _addNewTax,
child: _buildTaxInputFields(),
),
],
);

How can I make the leading flutter date icon clickable and selectable widget?

Below is my flutter code and I would like to make the leading calendar icon launch a calendar widget for date selection in the last textfield just before the raised button as marked below in code.
** widget starts inside stateful class**
#override
Widget build(BuildContext context) {
var db = DBHelper();
return Scaffold(
appBar: AppBar(
title: Text('Add'),
),
body: Container(
padding: EdgeInsets.only(top: 30, left: 50, right: 50),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
icon: Icon(Icons.bookmark), hintText: 'nickname'),
controller: nameController,
),
const SizedBox(height: 15),
TextField(
decoration: InputDecoration(
icon: Icon(Icons.date_range), hintText: 'date created'),
controller: otherController,
),
const SizedBox(height: 50),
RaisedButton(
onPressed: () {
db.saveAssets(Asset(
name: nameController.text,
other: otherController.text));
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyAssetsList()),
);
},
padding: EdgeInsets.only(left: 18, right: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
textColor: Colors.white,
color: Colors.lightGreen,
splashColor: Colors.lightGreenAccent,
child: const Text(
'Save',
style: TextStyle(fontSize: 20),
),
),
],
),
),
),
);
}
}
One more solution.
If you want only the calendar icon to be tapable (while still having similar design to the one you've provided):
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.date_range),
padding: EdgeInsets.zero,
onPressed: () {
print('Yay!');
},
),
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: 'Date Created',
),
readOnly: true, // Or wrap the input with AbsorbPointer if you do not want the field to get highlighted by taping on it
),
),
],
)
If you want to let the user input the date by typing - just remove the readOnly attribute from the input.

TextFormField losing value when changing focus

I am trying to move to other TextFormField but whenever I lose focus from first TextFormField text became empty, I search about this issue but I don't find any solution till now.
var _formKey = GlobalKey<FormState>();
Note note;
TextEditingController titleController=TextEditingController();
TextEditingController descriptionController=TextEditingController();
#override
Widget build(BuildContext context) {
TextStyle textStyle=Theme.of(context).textTheme.title;
titleController.text=note.title;
descriptionController.text=note.description;
// TODO: implement build
return WillPopScope(
onWillPop: (){
moveToLastScreen();
},
child:Scaffold(
appBar: AppBar(
title: Text("appBarTitle"),
leading: IconButton(icon:Icon(Icons.arrow_back),onPressed: (){
moveToLastScreen();
},),
),
body: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.only(top: 15.0,left: 15.0,right: 10.0),
child: ListView(
children: <Widget>[
//1st element
Padding(
padding: EdgeInsets.only(top: 15.0,bottom: 15.0,),
child: TextFormField(
validator: (String value){
if(value.isEmpty)
{
return "Please enter Title";
}
},
controller: titleController,
style: textStyle,
onSaved: (value){
debugPrint("Something changed in title Text field");
updateTitle();
},
/*onChanged: (value){
debugPrint("Something changed in title Text field");
updateTitle();
},*/
decoration: InputDecoration(
labelText: "Title",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
)
),
),
),
//2nd element
Padding(
padding: EdgeInsets.only(top: 15.0,bottom: 15.0,),
child: TextFormField(
validator: (String value){ //2nd step for form with validation
if(value.isEmpty)
{
return "Please enter principle amount";
}
},
onSaved: (value){
debugPrint("Something changed in Description Text field");
updateDescription();
},
controller: descriptionController,
style: textStyle,
/*onChanged: (value){
debugPrint("Something changed in Description Text field");
updateDescription();
},*/
decoration: InputDecoration(
labelText: "Description",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)
)
),
),
),
//3th element
Padding(
padding: EdgeInsets.only(top: 15.0,bottom: 15.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text("Save",textScaleFactor: 1.5,),
onPressed: (){
setState(() {
if(_formKey.currentState.validate()) {
debugPrint("Save Pressed");
_save();
}
});
}
),
),
Container(width: 5.0,),
Expanded(
child: RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text("Delete",textScaleFactor: 1.5,),
onPressed: (){
setState(() {
debugPrint("Delete Pressed");
_delete();
});
}
),
),
],
),
),
],
),
)),
));
}
Please suggest me I am new in flutter.
Remove titleController.text=note.title; descriptionController.text=note.description; from your build method and place it in initState method.
You will lose the value in the textField because those lines get executed anytime there is a rebuild, thereby replacing the values gotten from the textFields and replacing it with note.title and note.description which are empty at that point.
In other words, remove those lines and add this to your code.
#override
void initState() {
super.initState();
titleController.text=note.title;
descriptionController.text=note.description;
}