Soft Keyboard covers TextInput on the SlidingUpPanel flutter - flutter

This is the package am using , when I use a TextInput within the panelBuilder it has both the ListView and the InputTextField, however when I start typing the Soft keyboard covers the InputText field.
I also tried to add this line :
resizeToAvoidBottomInset: false, in the Scaffold plus this one in the Manfiest file
<item name="android:windowFullscreen">true</item> .
But no luck.
Below are the screenshots :
image one
[image two

Wrap the contents of your panelBuilder result in a Scaffold and don't change resizeToAvoidBottomInset. By default the resize is true which will move the content up to avoid being hidden by keyboard when it appears. A false setting prevents the resize from happening.
The below example is from the slide_up_panel package example, with the panelBuilder argument result wrapped in a Scaffold. (I'm not suggesting you wrap _panel like I've done below, it's just easier to show the example working this way. Likely better to use Scaffold within the _panel function itself.)
#override
Widget build(BuildContext context){
_panelHeightOpen = MediaQuery.of(context).size.height * .80;
return Material(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
SlidingUpPanel(
maxHeight: _panelHeightOpen,
minHeight: _panelHeightClosed,
parallaxEnabled: true,
parallaxOffset: .5,
body: _body(),
// WRAP panel contents in Scaffold
panelBuilder: (sc) => Scaffold(body: _panel(sc)),
// ↑↑↑↑↑↑↑↑
borderRadius: BorderRadius.only(topLeft: Radius.circular(18.0), topRight: Radius.circular(18.0)),
onPanelSlide: (double pos) => setState((){
_fabHeight = pos * (_panelHeightOpen - _panelHeightClosed) + _initFabHeight;
}),
),
To test yourself add a TextFormField to the bottom of the Widget _panel(ScrollController sc) method (around line 242)
SizedBox(height: 24,),
// ↓ Added for testing
TextFormField(
initialValue: 'type here',
onSaved: (txt) => null,
)
Then run the example, scroll the panel upwards and tap the TextField to have the keyboard slide up.

Related

How to fix a widget to the right side of a ListView on Flutter Web

I have a Flutter Web application where I need to show a widget on the right side of a ListView when I click an item and this widget should always be visible on screen. I can achieve my objective puting both on a Row and using a scrollable only for the ListView, but that requires the ListView to be wrapped by a widget with defined height.
Defining a container with height to wrap the ListView breaks the responsiveness when I resize the browser, as the container doesn't fit the height of the screen.
I thought of using the shrinkWrap property of the ListView so I don't have to wrap it in a widget with predefined height, but that makes the whole Row scrollable vertically, eventually causing the widget to leave the viewport.
I would appreciate if somebody knows how could I keep this right side widget fixed on screen so I can achieve my objective without losing responsiveness.
Here's something similitar to what I've got so far:
class PageLayout extends StatefulWidget {
const PageLayout({Key? key, required this.items}) : super(key: key);
final List<String> items;
#override
State<PageLayout> createState() => _PageLayoutState();
}
class _PageLayoutState extends State<PageLayout> {
final rightSideWidget = Container(
decoration: BoxDecoration(
color: Colors.red,
border: Border.all(color: Colors.white, width: 2),
),
height: 200);
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.49,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) => Container(
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(color: Colors.white, width: 2),
),
height: 200,
child: Center(
child: Text(
widget.items[index],
style: const TextStyle(color: Colors.white),
),
),
),
itemCount: widget.items.length,
),
),
Expanded(child: rightSideWidget),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
I want rightSideWidget to be always centered on screen or follow the scroll.
You can divide your screen into two sections, right section and left section; thereby being able to control behaviour of widgets in both sections.
Divide the overall screen into 2 proportional sections using a Row
widget
Put this Row widget inside a Container with height equal to screen height for preserving responsiveness | Use MediaQuery to get current height of page
Now left hand section can individually scroll, and on click of any option from this section you can define behaviour for right section; while keeping the left section constant throughout page lifecycle

Flutter - Bottom Overflowed Issue when Keyboard is Presented

I have a view that contains a Column of Widgets. One of the Widgets contains a button that will open a bottom sheet. Within that bottom sheet, a user can tap a TextField and open the keyboard which will keep the bottom sheet above the keyboard.
When I do this as-is, I get Bottom Overflowed by XXX Pixels. The yellow box is behind my bottom sheet, right above the keyboard.
I have tried wrapping the Column in a SingleChildScrollView but when I do that all of the Widgets in my Column disappear.
I have also tried wrapping in a Scaffold & that did not work either:
example:
Scaffold(
resizeToAvoidBottomInset: false, // tried setting to true as well
body: Column...
Any suggestions?
Here's some of the base setup:
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildWidget1(),
_buildWidget2(),
_buildWidget3(),
// When wrapped in a SingleChildScrollView
// this seems to be making everything in the column
// disappear...
Expanded(child: Container()),
etc.
],
);
}
void _bottomSheetButtonPressed(context) {
showModalBottomSheet(
barrierColor: Colors.transparent,
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(24),
topRight: const Radius.circular(24),
),
),
child: _showBottomSheetItemsWidget(),
),
);
},
);
}
The colors are transparent just so I can see what is happening behind the bottom sheet.
So, with this I am getting the Bottom Overflowed issue... and that is what I am trying to resolve.
Update:
After further debugging, I do see what I believe is making all my Widgets disappear. I have an Expanded Widget that has a child of Container to separate some of my Widgets.
The correct solution is indeed to wrap what you see into a scrollable widget such as SingleChildScrollView. But this can happen if and only if the contents of your scrollable widgets aren't infinite.
Indeed, the reason your widget simply "disappear" is an internal widget that forces infinite height (in this case, the Expanded widget), while the parent do not force a maximum height (the SingleChildScrollView), since it expects any number of widgets to be displayed. This causes an intrinsic / conceptual error (if you think about it) and therefore the framework throws an error.
It kinda depends on what you want to achieve, but as a rule of thumb in cases like this chances are that you want to wrap your scrollable widgets inside a SizedBox / Container / ConstrainedBox, so that you specify a height and therefore you force it to be not infinite.
In that case, your child widgets can use the Expanded logic with no issues.
Let me know if that helps.

Flutter bug with nested scrollviews

In my Flutter App, I have a Screen with a PageView that shows Cards. Some of the Cards have TextFields, so I put the Screen into a SingleChildScrollView, so that the Keyboard pushes the screen to the top and does not overlap. Here is an example of the code:
class DummyScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: PageView(
physics: NeverScrollableScrollPhysics(),
children: [
DummyCard(),
],
),
),
);
}
}
Now, some of the cards have a lot of TextFields and on smaller screens it would be too large. So I also put them into a ScrollView. This means I have a widget that contains a ScrollView, inside a PageView, inside a ScrollView:
(This is not the exact code, the styling parts are missing, obviously)
class DummyCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 14, vertical: 14),
child: Scrollbar(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
decoration: InputDecoration(hintText: "TextField 1"),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(hintText: "TextField 2"),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(hintText: "TextField 3"),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(hintText: "TextField 4"),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(hintText: "TextField 5"),
),
],
),
),
),
),
);
}
}
The PageView should not be scrollable, but should change the page on a button tap. So that is no problem. When The Keyboard is not opened, it is not a problem either, because the outer ScrollView is not scrollable, when the keyboard is not opened. The Problem occurs when I tap on a TextField and the Keyboard pops up. Now I have a scrollable ScrollView on the outside (the whole screen), and a scrollable ScrollView inside the Card, which leads to the following two problems:
The scrolling behavior is not good in general. When I tap the screen inside the Card, I can only scroll the inner ScrollView, even if I have already scrolled "to the end". So when I want to scroll the outer ScrollView, I have to tap the screen outside of the Card, which is not a very nice user experience.
When I tap a TextField, I want the screen to be pushed to the top. But as the TextFields are inside the inner ScrollView, it only pushes the inner ScrollView to the top, which often leads to the keyboard still overlapping the TextField.
I know that it is not a good practice to have 2 ScrollViews with the same scroll direction nested in each other. But it is the only solution that came to my mind. I definitely need the ScrollView inside the card. And I also want to push the screen to the top when the keyboard pops up, I don't want to shrink the screen (not possible with my layout). So, any ideas on how I can fix the above 2 problems?
Scaffold has a property which will prevent resizing the page on keyboard open, which is true by default. Try to set it to false
bool? resizeToAvoidBottomInset

Which widget can be used as a root widget (supports Text) in a new route without covering the entire screen in Flutter?

I am creating a new page route PopupRoute and using a Stack as the root of the new popup page. It works fine until I add Text to its children. Text will have two yellow lines underneath. I tried Material(child:Stack()) and Scaffold(child:Stack()). It can fix the yellow line issue, but it covers the entire screen and make the barrierDismissible not work.
Are there any other widgets can solve the Text yellow issues in my case?
You just need to wrap your Text widget inside a DefaultTextStyle widget. A DefaultTextStyle widget gets added implicitly by the Scaffold or Material widget.
DefaultTextStyle(
style: TextStyle(),
child: Text("This is a test"),
),
There might be a cleaner solution, but the first thing I thought of is wrapping Material inside of Align widget.
e.g.
showDialog(context: context, barrierDismissible: true, builder: (context) {
return Stack(alignment: Alignment.center, fit: StackFit.loose, children: <Widget>[
Container(width: 100, height: 100, color: Colors.blue),
Align(
child: Material(
type: MaterialType.transparency,
child: Text("TEXT"),
)
),
]);
});

Lot of blank space on top of keyboard when keyboard is visible in Flutter TextField

This is my code:
build(BuildContext context) {
return new Scaffold(
body: new SafeArea(
child: new ListView.builder(
itemBuilder: (itemBuilder),
itemCount: (1),
padding: kMaterialListPadding,
),
)
);
}
itemBuilder(BuildContext context, int index) {
return new TextFormField(
decoration: new InputDecoration(
border: const OutlineInputBorder(),
hintText: "What's on your mind?",
helperText: "5-500 characters",
),
maxLines: 3,
);
}
When I tap on the text field, keyboard opens but lot of blank space appears on top of keyboard as you can see in the picture (border of textfield is cut).
It happens because of the ListView. If I add just the text field to the body, appearance is fine.
The reason for lot of wasted space was because there was a Scaffold inside a Scaffold. Each scaffold adding space for keyboard. Removing one solved the problem.
Scaffold has a property resizeToAvoidBottomPadding.
Set this property false
For those who see white space after closing the keyboard, it can be caused by MediaQuery, where in my case I used MediaQuery around the base scaffold to fix the problem of using RangeSlider inside a drawer(using the RangeSlider will show the behavior of closing the drawer not changing the value of the slider ), where I used this:
MediaQuery(
data: MediaQueryData.fromWindow(window).copyWith(
gestureSettings: const DeviceGestureSettings(touchSlop: kTouchSlop)),
child: Scaffold(...)
But this however causes the white space that we saw after dismissing the keyboard, also it causes that when you open the keyboard on form, the screen won't scroll anymore.
So I add the media query solution only on the Scaffold where I used the drawer...
FYI, for those who uses Getx, I used it with bottom app bar, where we use:
Scaffold(
body: Obx(
() => IndexedStack(
children: controller.menuPages,
index: controller.navMenuIndex(),
),
),
and then after the main tabs, you use another Scaffold (I used the MediaQuery on this one )