Flutter: How to Bottom Center a Button in a ListView? - flutter

I need to bottom center a button that is contained within a ListView. By bottom, I mean at the bottom of the screen, or if the screen content is longer than the height of the screen, at the end of the content.
I can do this using a Column with a Spacer widget because the height is defined, however my screen has text input on it. If I use a Column instead of a ListView, the screen overflows when I'm typing.
How can I either
Bottom center a button, or
Use a Column but prevent the screen from resizing or overflowing when typing; I'd like it to ether be scrollable, or simply have the keyboard cover the screen content while typing.
Basic code example:
return Scaffold(
body: Center(
child: Container(
width: workingWidth,
child: Center(
child: ListView(children: <Widget>[
ScreenHeader("Tell Us a Little About Yourself"),
TextFormField(
maxLines: 16,
controller: bioController,
autocorrect: true,
textCapitalization: TextCapitalization.sentences,
maxLength: 500,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(paddingH5),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: colorPrimary)),
border: UnderlineInputBorder(
borderSide: BorderSide(color: colorMuted)),
hintText: "Enter your bio here...",
hintStyle: textMuted,
),
),
Spacer(), //This doesn't work because I am using a ListView instead of a Column
RoundedButton(
buttonText: 'Continue',
buttonStyle: buttonPrimary,
onPressed: () {}
),
],)
),
),
),
);

To use a Column without yellow/black stripes error when opening the keyboard, you need to wrap it into a SingleChildScrollView, but Spacer will not work in that case if you do not declare the height of its RenderFlex parent.
You can use MediaQuery.of(context).size.height to get the screen size on its context and set to your Container.
At the end you can achieve the desired layout with this:
return Scaffold(
body: SingleChildScrollView(
child: Container(
width: workingWidth,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
ScreenHeader("Tell Us a Little About Yourself"),
TextFormField(
maxLines: 16,
controller: bioController,
autocorrect: true,
textCapitalization: TextCapitalization.sentences,
maxLength: 500,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(paddingH5),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: colorPrimary)),
border: UnderlineInputBorder(
borderSide: BorderSide(color: colorMuted)),
hintText: "Enter your bio here...",
hintStyle: textMuted,
),
),
Spacer(),
RoundedButton(
buttonText: 'Continue',
buttonStyle: buttonPrimary,
onPressed: () {}
),
],
),
),
),
);

Related

Why is there whitespace when I add a SizedBox to a Textfield?

I have been trying to adjust the size of the text field but whenever I do it I have a lot of whitespace. Whenever I add a SizedBox it starts to add lots of whitespace. I have the TextField embedded in a MaterialApp and a Scaffold. So I am stuck on this.
This is without the SizedBox:
TextField(
decoration: InputDecoration(
hintText: "Enter Your Email Address",
border: OutlineInputBorder(),
contentPadding: EdgeInsets.all(30),
),
),
This is when you add the SizedBox:
SizedBox(
height: 100,
width: 100,
child: TextField(
decoration: InputDecoration(
hintText: "Enter Your Email Address",
border: OutlineInputBorder(),
contentPadding: EdgeInsets.all(30),
),
),
),
When there is no SizedBox
When the SizedBox is added
Probably you are not using Column, that's why when you wrap your TextField with SizedBox the screen takes SizedBox's width. At the top in body of Scaffold you should use Column.\
If you already have Column, please share your whole code for this particular page, and let me have a better look.
you can do like this.
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 45,
padding: EdgeInsets.fromLTRB(30, 0, 30, 0),
child: TextField(
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "Enter Your Email Address",
border: OutlineInputBorder(),
contentPadding: EdgeInsets.all(30),
),
),
),]
),
Currently, the width of the widget tree is the width of the widget whose width is maximum(Here, the width of the widget tree is equal to the width of the next button).
set width of sizedBox to double.inifinity, it makes the sizedbox to occupy the available width i.e screen width.
And the widget tree occupies the entire width.
SizedBox(
height: 100,
width: double.infinity,
child: TextField(
decoration: InputDecoration(
hintText: "Enter Your Email Address",
border: OutlineInputBorder(),
contentPadding: EdgeInsets.all(30),
),
),
)
Please accept the solution if solves your problem
contentPadding: EdgeInsets.all(3),
just change this -> dont need to use SizedBox widget
You are adding a sized box which have 100 width and also 100 height ,so the sized box will be a squared box .
By increasing the width of the sized box like 300 something you can easily do this or I suggest you a way that a text field will be easily fixed in you code .
I hope this code will help you
Flexible(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(
labelText: 'Enter Something',
border: OutlineInputBorder(),
hintText: 'Enter Something ',
),
},
),
),
),
I generally used 'Sized Box' for spacing purpose in my flutter project
Use the below written code to understand how SizedBox works as spacing
class _sampleState extends State<sample> { #override Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Column(
children: [
SizedBox(height: 80,),
Text("Signup",style: TextStyle(fontSize: 30),),
SizedBox(height: 20,),
TextField(
decoration: InputDecoration(
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(10.0),
// ),
filled: true,
hintStyle: TextStyle(color: Colors.white),
hintText: "Username or email",
fillColor: Color(0xff313F4D),
),
),
SizedBox(height: 50,),
ElevatedButton(onPressed: (){},
child: Text("Next"))
],
)),
);

Flutter TextFormField focus

So I was coding the search bar and I used the TextFormField widget but I have a problem with this. I have two screens and the widget is in both screens. On the first screen when you tap the TextFormField it reroutes you to the second screen and there I have set autofocus to true. The only problem is that once you done searching for accounts and try to route back to the previous screen the TextFormField autofocuses again and I do not want it like that.
And here's my code.
\\\ appbar
title: Padding (
padding: const EdgeInsets.only(left: 5.0, right: 5.0),
child: TextFormField(
autofocus: false,
cursorColor: Colors.purple,
onTap: () {
FocusScope.of(context).unfocus();
TextEditingController().clear();
Get.to(() => const SearchPage());
},
decoration: InputDecoration(
suffixIcon: const Icon(
MdiIcons.databaseSearch,
),
labelText: 'Go Wild',
labelStyle: GoogleFonts.parisienne(
fontSize: 21.0,
),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.purple),
borderRadius: BorderRadius.circular(34.0),
),
),
),
),
),
/// body of the Scaffold
I have tried different answers but none of them helps. Please help me

iOS search bar animation in flutter

I want to add a animation in a search bar when the user taps on it (just like the animation in whatsApp or telegram [only in iOS])
here is the animation
I used Hero widget to do so but the widget is not working, I don't know why. Here is my code for it
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
//some widgets above the search bar
Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
//some more widgets here inside the column
])
This is part of code for 1st page and the other page is just the search bar.
This is the other page which is almost the same
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
),
);
}
Also is there any other way to do it?
EDIT: It's now working fine with Hero widget but it does not show that exact behaviour as in the above gif. How should I do that, if someone has any other method to achieve that, can also answer.
Hero is used when moving between different pages here(in the above animation) we are not navigating to any other page, so, remove the Hero widget
This can be done with Transform.translate in combination with Opacity() widget in Flutter.
Wrap the respective widget with Transform.translate create a Tween Animation and change its height with the help of Offset(dx, dy) (in this case dx will be 0 and dy will be the changing height), negative dy value will move the widget upwards. Also wrap it with Opacity() and change the value with the changing value of height.
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Transform.translate(
offset: Offset(0, animatedHeightFromTweenAnimation)
child: Opacity(
opacity: animatedHeightFromTweenAnimation/maxHeightValue;
child: anyWidget()
)
)
Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),//container
RaisedButton(
onPressed: () => controller.forward(), //here controller is animation controller
//the above line will start the animation
child: Text("press it"),
),
//some more widgets here inside the column
])

Flutter when text is bigger than input, text disappears

The problem is that when the text is bigger than the input size, the text just disappears and I don't know why.
Here is my code:
TextField(
focusNode: _focusEmailNode,
controller: _emailController,
decoration: InputDecoration(
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: txtEmailBoder),
),
hintText: 'Email',
),
After searching through many sites, I finally got a solution. You can solve this problem by giving decoration and maxlines in the textfield. Give isDense as true in InputDecoration
Example:
Container(
height: 20,
width: 100,
child: TextFormField(
maxLines: 1,
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.fromLTRB(5.0, 1.0, 5.0, 1.0),
),
onChanged: (value) {
print(value);
},
),
);
if you don't give content padding then your text will be cut from the middle, like below.
Be careful when you give padding, you should give padding as needed by your textfield's height. If you give wrong padding then also your text will be invisible.
You need to add
contentPadding: EdgeInsets.zero
to your InputDecoration
Give text field an input formatter with desired length of the text like this:
inputFormatters: [
LengthLimitingTextInputFormatter(50),
],
And then have content padding set to like this :
contentPadding: EdgeInsets.fromLTRB(5.0 , 20.0 , 5.0 , 20.0),
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.fromLTRB(5.0, 50, 5.0, 10.0),
alignment: Alignment.center,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
),
hintText: 'Email',
),
)));
}
To Prevent this disappearing use decoration as InputDecoration.collapsed(hintText: "Search Customer")
Full Code is TextField(decoration : InputDecoration.collapsed(hintText: "Search Customer"), textCapitalization: TextCapitalization.sentences)

How to make the TextField expands in flutterwhen the user types in it?

I am setting a text field which will expands when Enter is pressed in the keyboard
when i tried to set null in max lines it does not show the text inside text field
i even set that expands = true
i used media query size in somewhere which is size.height in the code
i wrapped the text field within the Flexible widget
and add some padding then the total flexible widget is wrapped within a Row
and finally the row is wrapped within a Container
so this code is not working help me to fix this
Container(
height: size.height * .059,
width: double.infinity,
child: new Row(
children: <Widget>[
new Flexible(
child: Padding(
padding: EdgeInsets.only(right: size.width * 0.007),
child: new TextField(
controller: _textFieldController,
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
maxLines: null,
expands: true,
style: TextStyle(color: Colors.black),
cursorColor: Colors.blue,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(color: Color(0xff8e9291))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(color: Color(0xff8e9291))),
prefixIcon: Icon(
Icons.message,
color: Color(0xff8e9291),
),
hintText: "Type a message",
hintStyle: TextStyle(
color: Color(0xff8e9291),
),
),
),
),
),
FloatingActionButton(
backgroundColor: Colors.blue[400],
onPressed: () {
},
tooltip: 'Send',
child: RotationTransition(
turns: AlwaysStoppedAnimation(-35 / 360),
child: Icon(
Icons.send,
size: 20,
)),
),
],
),
),
this is the Text field i'm using..
You could remove the height of the Container since that will make a fixed height, and remove the expands of the TextField since that is to make it to fill its parent height.
You could set MaxLine property to null 'maxLines: null`
this will enable textField to Expand Vertical