Flutter: How to add bullets points in a TextField? - flutter

How to add bullets points in a TextField widget similar to the Notes app in IOS?

You can use Unicode code to achieve this. Add the following Unicode ( \u25EF ) to your TextField using TextEditingController. You may also need to change the position of the cursor when adding text to your TextEditingController. This depends on your requirement and you will understand when you test this.
TextEditingController _textController = new TextEditingController();
_textController.text = " \u25EF ";
Yes. of course you need a custom button or something to trigger this event like in the note of IOS.
You can create a custom keyboard with an extra button to add bullets or a floating deck with a button like the Note app. Or simply give a button on the screen.

You need to create a checkbox (or similar button) manually when user select it and add to left of textfield. You can define variable on a Row and initialize to Container. Something like that:
Widget widget = Container();
[...]
Row(
children: [
widget,
Expanded(child: TextField(...))
],
);
[...]
//this activate bullet point
void functionCheckBox(){
setState({
widget = Checkbox(value: value, onChanged: onChanged);
});
}
I dont know if it's the best solution or if exists a plugin that does something like that.

Related

Animating Text widget content based on change of variable

How can I animate the change from a Text widget with a particular String to a new String which is dynamic, i.e., I don't know what it'll be beforehand ?
For example, let the widget be Text('a'). Later I want it to animate to Text('b'), maybe a after a button being clicked by a user.
Store the user input in a variable and display it in the Text widget. For example,
var input = value;
inside the widget you can use Text('$input') or directly Text(input) to display it

How can I let my DropdownButton affect my TextFormField

I think this is probably not too complicated, but I am new to coding and don't understand this, nor could I find an explanation online that I could understand.
In my app my AppBar includes both a title and a bottom, the title has been just text, and the bottom was a TextFormField users used to search through my database.
Recently I updated the title to a DropdownButton, and I wanted to use what the user selected there to change the the search parameters in my TextFormField (so that it would search different columns in my database).
I built the DropdownButton in a separate document, and then inserted it into title. Finding how to use it has been more tricky.
I built some sort of callback, which worked to print in my console, but I couldn't figure out how to pass the information into my TextFormField.
class HomePage extends StatelessWidget {
HomePage({Key key, this.title}) : super(key: key);
_handleValueReturned(value) {
if (value == 1) {print('This works');} if (value == 2) {print('This works not');} else {return null;}
}
...
appBar: AppBar(
title: DropDownButton(
valueReturned: _handleValueReturned,
),
bottom:...
...
Do I have to use some sort of provider or "of" or packages like Eventifier or ChangeNotifier? I couldn't figure out how all these things worked.
According to my understanding, you are trying to set the selected value from the DropDownButton in the TextFormField, if that is what you are trying to do then create a TextEditingController and add it to the TextFormField then set its text property inside your callback which is called _handleValueReturned, but you have to rebuild the widget so the TextFormField is rebuilt with the new value, of course, you have to convert your widget into StatefulWidget to do that.
Creating and initializing the TextEditingController:
final _controller = TextEditingController();
Attatching the controller to the TextFromField:
TextFormField(
controller: _controller,
...
);
Changing the value of the controller inside _handleValueReturned callback:
_handleValueReturned(value) {
...
setState((){
_controller.text = value; // It can be any String according to your scenario.
});
}
Side Note: When you are dealing with a simple text input such as one input field then you do not have to use TextFormField and you can simply replace it with TextField.
I hope I got your problem correctly and I hope it got fixed.

Flutter toggle Radio widget

I'm using Radio widgets to set the user gender. These Radio button widgets are designed very well to handle the selection changes act accordingly, but I does not find a solution to somehow deselect one already selected option. I would like the gender radio group to be optional. But after user selects let's say female, he/she can change the selection to male, but can't deselect the female/male option. (So that none of the option is selected.)
There is only an onChanged property and it only changes if the gender changes. No such thing like onTap or something similar. So no matter if I check that gender if it's the same, onChanged won't be called.
For that reason I tried to use a GestureDetector which should solve this issue (with this I should be able to deselect the already selected option) but in case of radio widgets it does not work. I also tried to change it's behavior property but it did not help either.
Here is the function which I use to create gender radio option with a text in a Row.
Widget _buildRadioWithText(final genderChangeNotifier, final Gender genderParam, final String genderText) {
return Row(
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
child: Radio<Gender>(
visualDensity: VisualDensity.compact,
value: genderParam,
groupValue: genderChangeNotifier.gender,
onChanged: (Gender gender) {
genderChangeNotifier.gender = gender;
print(gender.toString());
},
),
onTap: () {
if (genderChangeNotifier.gender == genderParam) {
genderChangeNotifier.gender = Gender.NA;
print("Not answered!");
}
},
),
GestureDetector(
onTap: () {
if (genderChangeNotifier.gender == genderParam) {
genderChangeNotifier.gender = Gender.NA;
print("Not answered!");
} else {
genderChangeNotifier.gender = genderParam;
print(genderParam.toString());
}
},
child: Text(
genderText,
style: TextStyle(
fontSize: _fontSize,
),
),
),
],
);
}
Function call:
_buildRadioWithText(genderChangeNotifier, Gender.FEMALE, "Female"),
_buildRadioWithText(genderChangeNotifier, Gender.MALE, "Male"),
genderChangeNotifieris just a provider to set and get the Gender value and notify listeners when a Gender is set.
final GenderNotifier genderChangeNotifier= Provider.of<GenderNotifier>(context);
GestureDetector's onTap works well when I tap on the Text widget. It selects then deselects the option just as I'd like to but in case of the Radio widget onTap is never called.
Any idea how to achieve the deselection when I tap/click on the Radio widget itself? And why the GestureDetector that wraps the Radio does not register the tap events?
The GestureDetector's onTap is not being called because the GestureDetector inside the Radio widget is taking priority. By default, when two GestureDetectors are competing for input, only one will "win". In this case, the winner is the one in the Radio. This article discusses "GestureArenas" and how you can allow both GestureDetectors to process input.
However, consider whether allowing the user to deselect the radio button is the correct solution. Radio buttons are designed not to be deselected once the user has selected an option. You might instead:
Offer a third, "I'd rather not say" option
Use toggleable buttons instead of a radio group
Use a dropdown menu instead of a radio group
See this answer for more info on the usability aspect of this.

Overwrite Paste Event for TextFormField

I have a TextFormField. Usually you can use the selection toolbar to copy/paste/select all and so on using long tap/double tap.
I want to overwrite the Paste Event. It shouldn't simple insert the current clipboard data but open a popup with several options to insert.
Is it possible to catch and overwrite the Paste event in any way? I saw something like handlePaste() for SelectionControls, but I don't know how to add this to my TextFormField.
Thanks in advance!
AFAIK, you can't exactly 'intercept' the standard toolbar. However, what you can do is to prevent the standard toolbar and make your own.
You can use wrap the textfield/textformfield under IgnorePointer. It will hide any tap gestures on the text field. Below is the code snippet.
IgnorePointer(
child: TextField(
focusNode: _textfieldFocusNode,
controller: _controller,
),
)
Now,you can wrap this IgnorePointer under GestureDetector and show your own menu. Like this :
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScope.of(context).requestFocus(_textfieldFocusNode);
},
onLongPress: () {
showMenu(____
}
)
This produces the result below and the sample implementation code is here
Found a way to override paste event. I'm not sure, that it is a right way, but it works.
In every TextField you have selectionControls, that provides a way to show and handle toolbar controls.
So, to catch paste event first:
create your own version of selection controls, for example
class AppCupertinoTextSelectionControls extends CupertinoTextSelectionControls {
AppCupertinoTextSelectionControls({
required this.onPaste,
});
ValueChanged<TextSelectionDelegate> onPaste;
#override
Future<void> handlePaste(final TextSelectionDelegate delegate) {
onPaste(delegate);
return super.handlePaste(delegate);
}
}
class AppMaterialTextSelectionControls extends MaterialTextSelectionControls {
AppMaterialTextSelectionControls({
required this.onPaste,
});
ValueChanged<TextSelectionDelegate> onPaste;
#override
Future<void> handlePaste(final TextSelectionDelegate delegate) {
onPaste(delegate);
return super.handlePaste(delegate);
}
}
then, initialise it in your state (for example in StatefulWidget it can looks like that, see below). To study how it used in TextField please see source here
TextSelectionControls? _selectionControls;
#override
void initState() {
if (widget.onPaste != null) {
if (Platform.isIOS) {
_selectionControls = AppCupertinoTextSelectionControls(
onPaste: widget.onPaste!,
);
} else {
_selectionControls = AppMaterialTextSelectionControls(
onPaste: widget.onPaste!,
);
}
}
super.initState();
}
Use callback for onPaste with a type ValueChanged<TextSelectionDelegate> and you can use the same code the Flutter team used to get Clipboard data:
Future<void> onPastePhone(final TextSelectionDelegate? delegate) async {
final TextSelection selection = phoneController.selection;
if (!selection.isValid) {
return;
}
// Snapshot the input before using `await`.
// See https://github.com/flutter/flutter/issues/11427
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
final text = data?.text ?? '';
if (text.isEmpty) {
return;
}
}
Then use selection controls in your TextField.
TextFormField(
selectionControls: _selectionControls,
)
Hope it helps.
I search for this problem. I think there is no proper way to solve this problem. I read about the Textfield class and found two solutions for it.
if you check TextField widget you can find that it will use EditableText to show its simple Text input. EditableText has a selectionControls property. this property is used to render the selection toolbar. also, I found that material and Cupertino have different implementation of it.
1st Solution: you can create your own custom TextField that will use EditableText and pass your custom selectionControl to your widget. I think this gonna be a very hard job to do. create your own implementation of the widget, handling animations, and...
2nd Solution: You can simply copy all related files of TextField in a new file and update it as you want. for this solution, I create a repo in GitHub. you can checkout source code to understand how you can show a dialog in the paste option. and this is how the code should work.
note: I just simply update paste function of the Material implementation of selectionControls. if you want you can also update the Cupertino selectionControls too.
note: also I added documents in everywhere I change the code.

I want to get the value from a TextFormField when i press a RaisedButton in flutter

TextFormField has it's own property to perform actions, called "onFieldSubmited".
But i want to get the value from the TextFormField, when i press a RaisedButton or something.
How can i do it?
All you need is a TextEditingController
There is a cookbook for this in flutter's own website. Wonder how you missed it.
Use TextEditingController to get the value of a specific TextField.
https://flutter.dev/docs/cookbook/forms/text-field-changes
[...]
TextEditingController controllername = TextEditingController();
[...]
TextField(
controller: controllername, //...Rest of the code
)
Use the controllername.value to get the current value of a Textfield for that particular moment.