I have a layout with two TextField and I am worried about all the items being resized when the keyboard is shown.
The layouts with and without the keyboard are in the picture below.
When the keyboard is shown all the widgets (TextField Text and Button) resize to the top.
As my widgets are wrapped into a SingleChildScrollView, even if the screen is small we can scroll to see all the items, therefore, there isn't a problem.
Widget _buildCamposLogin() {
return Form(
key: _formKey,
child: Container(
margin: EdgeInsets.only(bottom: 50.0, left: 30.0, right: 30.0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_buildLoginText(),
_buildCampoCPF(),
_buildCampoSenha(),
_buildSubmitButton(),
_buildCadastroText(),
],
),
),
),
);
}
So, the problem is I feel weird about moving everything to the top, shouldn't be better to move only the TextField which was focused and the other things above this TextField, instead of moving everything above and below the TextField which was focused.
If you think this is better, what would be the solution to move only the TextField and widgets above to the top?
Why my question is not duplicated
In the marked question, the guy asks how to prevent the keyboard from moving the widgets. And the answers say to set resizeToAvoidBottomInset: false in the Scaffold. That's is completely different from what I am asking.
I do want the keyboard to move the widgets to the top as it does. The problem is that it moves all my widgets, the 2 TextField the RaisedButton and the 2 Text at the bottom. I would like to move only the TextField which was shown as the following example.
Note the difference between these two pictures below and the others I've already uploaded.
Related
I want same way so that when keyboard appears on screen when user clicks on TextField, screen should be animate up of by size of keyboard automatically not manually.
If anybody know any way it is really helpful..
Note :
Widgets in column are not occupying complete screen
child: SingleChildScrollView(
child : Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......
I done this with MediaQuery but not animating up but when keyboard goes it animating down properly.
resizeToAvoidBottomInset: false, added already
by set padding botttom with MediaQuery.of(context).viewInsets.bottom) means that we are add padding bottom with same height with keyboard.
I guess there are some widget as before the SingleChildScrollView. if you are set the padding on children, padding will be add only to the children. so it cant automatically set new padding.
Solution: Use the padding on top of widget tree.
if there is any widget before SinglechildScrollView, set the padding there.
Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: SingleChildScrollView(
child: Column(
....
i have broadcast screen ( in full screen) . i have textField on the same broadcast screen on the bottom so we have here Stack like following
Scaffold(
body: Stack(
alignment: Alignment.bottomCenter,
children:[
broadCastScreen()
TextField()
]
)
)
so my layout looks like this
now when i tap on the text field all scaffold resize its self because of the keyboard show up
the good point in this part that my textfieldalways smoothly move to be up the keyboard visible
but the bad part that my broadcast screen resize its self inappropriately for the user experience
so i decide to prevent that annoying party with set resizeToAvoidBottomInset to false
well now everything sound good , but i noticed that my keyboard covering my text field
so How Can i use resizeToAvoidBottomInsetto all my widgets except my textfield part ?
i tried to wrap my textfield with another scaffold with set resizeToAvoidBottomInset to true
and scaffold color to transparent so others widgets be visible and tis work as expected but i completely faced problems with GestureDetector pointers in my first scaffold and thats because my second scaffold stack it
another solution i tried programmatically to set my textfield bottom padding to be the same of my keyboard height using EdgeInsets.fromWindowPadding(WidgetsBinding.instance.window.viewInsets,WidgetsBinding.instance.window.devicePixelRatio);
but that's not perfect way because there is some delay with height keyboard value like 900 millisecond to get the keyboard height Furthermore it i tested it on several difference phones and i got null height with some devices It does not guarantee the measurement of all phones
any other perfect way friend ?
Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
fit: StackFit.expand,
children: [
SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Content()
]
Positioned(
bottom: 0,
child:
child: TextFormField(
decoration: InputDecoration(filled: true, fillColor:
Colors.red
),
),
)
],
),
);
Simply Wrap your content in SingleChildScrollView and wrap your TextField in Positioned widget set bottom parameter of Positioned to Zero, add
fit: StackFit.expand,
Note: Don't forget to add above code to your Stack Widget
Let's try to do something like this
Scaffold(
body: Stack(
alignment: Alignment.bottomCenter,
children:[
Positioned.fill(child:
broadCastScreen()),
Position(
bottom:0,
child: TextField())
]
)
)
In the screen below, I have the following text "By creating an account ...." that I would like to always keep at the bottom of the screen and should never scroll up with the keyboard.
Currently the text is placed in bottom sheet but unfortunately, the bottom sheet does scroll up with the keyboard.
Using resizeToAvoidBottomInset: false in the Scaffold will not help since it will make all screen ignore the keyboard.
Is there any way to keep the text at the bottom of the screen and have it ignore the keyboard?
I was able to find a basic solution to this.
I placed the terms and conditions text in the bottomNavigationBar property of the Scaffold like this.
Scaffold(
bottomNavigationBar: const TermsAndConditionsText(),
....
....
)
The trick is to use the MediaQuery.of(context).viewInsets.bottom
The value of .bottom will be updated whenever the Keyboard shows up.
To achieve what you want
1- Define the resizeToAvoidBottomInset: false in the Scaffold.
2- Wrap your "form" in a Stack widget.
3- Add your Widgets which should stick at the bottom of the screen at the same level of your "form" in an Align or Positioned
Stack(
children: [
child: Column(
... //Form
),
const Align(
alignment: Alignment.bottomCenter,
child: Text("Terms And Conditions"),
)
],
),
4- And now the magic trick : wrap your "form" in a Padding with the viewInsets.bottom value
Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
...// Form
),
),
const Align(
alignment: Alignment.bottomCenter,
child: Text("Terms and Conditions"),
)
],
),
My solution looks more like a "hack" than a proper solution, but I never found any official documentation solving this kind of "problem".
I'm trying use IndexStack in my app. But I have a problem with Stack and ElevatedButton. I trying press button and it don't response anything to me. But the blue button bellow is still working well
Thank for concern about my issue.
Codepen: https://codepen.io/sucanabo/pen/xxqPrRw
How Stack widget works, is that it takes the first child from the children list that you provide it and makes it the base of the rendering.
Whatever children you provide it after the first child, will be rendered on top of the base child.
So, when your Positioned child is becoming the base, your ListView child (which is the second in the children list) is being rendered on top of your Positioned widget, which is hence blocking all the interaction.
If you want this to work with your architecture, move the ListView as the first child and your Positioned as the second child, like this,
Stack(
clipBehavior: Clip.none,
children: [
// First the ListView
ListView(
padding: EdgeInsets.fromLTRB(20.0, 50.0, 20.0, 20.0),
children: [],
),
// Then the Positioned
Positioned(
top: -35.0,
left: 0,
right: 0,
),
],
),
I have a tree structure like the following, basically a Row inside a SingleChildScrollView, where the children of the Row are Draggables.
Positioned(
top: 250,
left: 30,
child: Container(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: initialState.map((f) => LongPressDraggable(
child: f,
feedback: Transform.scale(scale: 0.4, child: f),
childWhenDragging: Container(),
)).toList(),
),
),
),
),
The problem is that the Draggable seems to be consuming any gesture, so that, when tapping (long press in this case), the drag effect works, but no other gesture seems to work, so basically scroll does not respond.
I tried using, instead of LongPressDraggable, a regular Draggable and use affinity property, but even with that, the scroll does not respond, just the drag.
Any help or suggestion?
For anyone else dealing with this (at the end stupid situation)....
It turns out that the problem does NOT come from the Draggable itself.....
For some reason, putting the SingleChildScrollView inside a Positioned prevents this from scrolling....
Found a clue in this bug: bug report
So that, the solution proposed in the bug about giving double values to the top, bottom, left, right properties of the Positioned did not work well for me.
So...I solved it by using exactly the same code, but using Align widget instead of Positioned.