Scroll Flutter's multi-line TextField to end - flutter

I have a periodic function which appends text to a TextField.
For this purpose I set a TextEditingController and invoke: controller.text += someText.
However, when the TextField is scrolled and text is added, the TextField automatically scrolls back to the top and the just appended text gets out of view.
Is there any way to change the scroll behavior?

Set the selection using the TextEditingController.
This will prevent the TextField from rebuilding every time and/or moving the cursor to the start of the TextField.
TextField(
controller: textEditController,
onChanged: (content) {
textEditController..text = someText
..selection = TextSelection.collapsed(offset: textEditController.text.length);
},
)

I don't know if this can serve you already today but in case someone else sees the publication I hope that helps, I'll say that I do this with a SingleChildScrollView() and I set the reverse property to true. I have to say that I don't use a TexField(), you use a Text(), but it behaves well and every time the text increases a line automatically the reverse property of the SingleChildScrollView() causes it to scroll down and always see the last thing that is being written.
This is a small example of how I do it in my code:
Container(
alignment: Alignment.bottomRight,
height: size.height*0.044,
child: SingleChildScrollView(reverse: true,child: Text(valorOperacion1, style: GoogleFonts.exo(color: tema.hintColor, fontSize: 18.0.sp, fontWeight: FontWeight.w600,),))
),

Related

How to show overflow on textfield's value (ellipsis)

How can I achieve something like this?
That the textfields value is showing (...) when text is bigger than the remaining space
When the text input
I know we can use overflow: TextOverflow.ellipsis, in a Text widget. How can we do something similar in textfield value?
i think for now ,there is no parameter to set overflow on TextField
since the issue still open on official repository here.
maybe you can use another plugin like auto_size_text_field
AutoSizeTextField(
controller: _controller,
overflowReplacement: Text(
_controller.text,
style: const TextStyle(overflow: TextOverflow.ellipsis),
),

Is there a way for the showTimePicker() in Flutter to not reset any value in TextInputField?

I implemented a page in my Flutter application that has a text input field and 2 time pickers that are activated by pressing the button to make them appear. The issue is that if I have a new value in the TextInputField and use one of the time pickers, after I'm done what I have typed in the input field will just reset.
Code snippet from the input field:
SizedBox(
width: 350,
child: TextField(
controller: titleController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Title',
),
onChanged: (value) {
title = value;
},
),
),
I've tried keeping the value of what is being typed in through a titleController and I have also attempted using the onChanged() method and a separate variable to keep the value in there. These solutions both didn't work for me, however. Is there any other solution to this issue?
If your TextField inside a stateless widget it will keep clearing the value of the controller everytime something pop on the screen, so try to put your TextField inside a stateful widget

Flutter: TextField will not scroll down when new lines are added

Update: this problem may be because of setting the TextField's 'readOnly' attribute to true. If so, I still need to make sure the keyboard does not pop up, since I set readOnly to true to disable the keyboard.
BACKGROUND
My app adds letters and newlines from a custom button widgets to a display that has a TextField widget. I do not use a keyboard for this. I use the Provider package and a ChangeNotifier called AppBrain to manage state. AppBrain has the text information and edits it when a letter is selected from the selection bar.
The textfield is a scrollable widget when there are too many lines to fit in its dimensions. But whenever I add letters and a new line of text is created, the textfield does not scroll down and the cursor and edited line is obscured.
I would like to know an easy way to scroll until the cursor is visible again. (When the cursor is at the end of the text, I can scroll to the bottom. When it is in the middle of the text, I just need to scroll it one line down.)
POSSIBLE FIXES
When I reenable the keyboard to edit the TextField, it does it automatically. If anyone knows how the keyboard edits the TextField, I might be able to add that to my addWord function.
I tried using a ScrollController to scroll the TextField using its animateTo() function. The problem I have is that I usually need to just scroll down 1 line, but I don't have the exact pixel height of my lines of text. I also don't know when a line wraps to a new line, which would require a scroll down.
Perhaps if I had the position of my cursor, I could use it along with my TextField's dimensions to scroll down accordingly.
Picture of my app
CODE
Textfield widget in Text Display
Portion of code in Text Display
...
Positioned(//Text Display
top:0,
left:0,
width:kScreenDim.dx,
height:290,
child: Container(
color: kAppBarBackgroundColor,
child: Container(
padding: EdgeInsets.only(left: kTextMargin),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft:Radius.elliptical(17,20),
topRight: Radius.elliptical(17,20)
),
color:kTextDisplayColor
),
child: Consumer<AppBrain>(
builder: (context,appBrain, child)=> TextField(// <<=====
controller: appBrain.textDisplayController,
scrollController: appBrain.textDisplayScrollController,
readOnly: true,
autofocus: true,
showCursor: true,
maxLines: null,
decoration: null,
cursorColor: Colors.red,
style: TextStyle(fontSize: kTextFontSize,)
),
),
),
),
),
...
Enter Button
Example of a button that adds a letter to the TextField
BottomButton(//ENTER BUTTON
onPressed: () {
var appBrain = Provider.of<AppBrain>(context, listen:false);// <<===
appBrain.addWord('\n');
},
label: 'Enter',
color: kEnterButtonColor,
)
App Brain
Relevant portions of AppBrain, a ChangeNotifier. The main summary of addWord is that I directly edit textDisplayController.text and textDisplayController.selection.
class AppBrain with ChangeNotifier {
...
TextEditingController textDisplayController = TextEditingController();
ScrollController textDisplayScrollController = ScrollController();
...
...
void addWord (String aWord){//Inserts/replaces word into text of TextDisplay
//DIRECTLY EDITS textDisplayController.text and textDisplayController.selection
String displayText = textDisplayController.text;
List<int> selectionRange = getSelectionRange();
int cursorCharIndex = selectionRange[0]; //position in text
//position in _numTChars
int newCursorDisplayIndex = getCursorDisplayIndex(cursorCharIndex);
//Update text and _numTChar.
//If there is a highlighted selection of text to be replaced,
if (selectionRange[0]!=selectionRange[1]){
int lidx = selectionRange[0];
int ridx = selectionRange[1];
int lDisplayIdx = getCursorDisplayIndex(lidx);
int rDisplayIdx = getCursorDisplayIndex(ridx);
textDisplayController.text = displayText.substring(0,lidx) + aWord; <<===
if (ridx < displayText.length) {
textDisplayController.text += displayText.substring(ridx);
}
_numTChars[lDisplayIdx] = aWord.length;
_numTChars = _numTChars.sublist(0, lDisplayIdx+1) +
_numTChars.sublist(rDisplayIdx);
}else {//Insert character at the cursor
if (displayText.length == 0 || cursorCharIndex == displayText.length) {
textDisplayController.text += aWord;
} else {
textDisplayController.text = displayText.substring(0, cursorCharIndex)+
aWord + displayText.substring(cursorCharIndex);
}
_numTChars.insert(newCursorDisplayIndex, aWord.length);
}
//place the cursor in the correct position.
cursorCharIndex += aWord.length;
// <<===
textDisplayController.selection = TextSelection(
baseOffset: cursorCharIndex,
extentOffset: cursorCharIndex
);
notifyListeners();
}
...
}
When keyboard pops up it covers bottom of you widget. you should use MediaQuery to get bottom padding after keyboard pops up.
wrap your page in a Padding widget and set the bottom like this.
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: YourWidget()
when keyboard is not visible the value of
MediaQuery.of(context).viewInsets.bottom is zero, but when keyboard pops up the value changes to somethong like 253.6.

Flutter, widget next to the last letter of TextFormField

I want to move the box that is full of red background over there to the position of the empty box.
In other words, I want to insert a container right next to the point where TextFormField ends.
Is this something that can be implemented in Flutter? Or is there no way?
-- UPDATE
I actually want to add a "send" Icon to the end of the text. All the examples I looked up were always going to the end of the Containers due to Rows, as shown in the photos I posted. Since the position of the send icon will always change, depending on the length of the text, in real time, this problem feels very difficult to me. and also for your information, this is not Text, but TextField or TextFormField widget.
Unfortunately, there is no way of doing this since TextFormField accepts string only and not a widget. Also, according to material guidelines, any such widget should be at the end of the text field as a suffix such as:
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: "Enter a message",
suffixIcon: IconButton(
onPressed: () => _controller.clear(),
icon: Icon(Icons.clear),
),
),
)
May I ask what is the purpose?! maybe we can help find better solution then?
but if we have to then I can think of 2 ways.
1- Include the box as a Text - For example ▀ (Alt + 223)
var box = ▀
Text("efwewewefwewefe$box"),
2- Option 2: Wrap in a Stack widget
Stack(
children: [
Text("efwewewefwewefe"),
Container(height:5, width:5, color: Colors.red]),

Flutter: How to make such Edit text and remove the unexpected layout padding

I'm trying to implement this design:
i'm very beginner to flutter, and what i'm getting is this:
I don't want you guys to get me wrong, i'm not asking for someone to implement this for me.
i need guidance on how to:
remove the layout padding.
make a textview and edit text side by side look like one widget.
remove the space between the edit texts.
implement the CheckBox (i tried a row with check box and text, didn't work)
show a proper arrow in "Sign In" (instead of ->).
just some explanations, guidance and any documentation or tutorial that could be good for my case.
Here is my code
remove the layout padding.
make a textview and edit text side by side look like one widget.
Im not sure of this if your talking about inside TextFormField you can use contentPadding inside InputDecoration. But based on your layout design, you can separate the Label in TextFormField and create your own label text
Row(
children:[
Text("LABEL"),
Expanded(
child: TextFormField(),
)
]
)
4.implement the CheckBox (i tried a row with check box and text, didn't work)
Row(
children: [
Checkbox(
value: isValue,
onChanged: (bool value) {
setState(() {
isValue = value;
});
}),
Text("SOME TEXT"), //Read RichText widget for your design
],
),
For you arrow -> sign in
Try using Icon() widget