flutter widget hides behind keyboard when it opens - flutter

I am trying to create a chat screen with text field at the bottom and whenever it is clicked the keyboard comes up and the textfield should be on top of the keyboard but my own isn't doing what it's supposed to do. I have checked other similar questions and answers on google, stackoverflow and github but it still stays the maybe because in mine am using constraints: BoxConstraints(maxHeight: 160), which might be what is causing it but i don't really know
This my code
class _ChatSectionState
extends State<ChatSectionState> {
List<File> images = List<File>();
getMultiFile() async {
await pickFileFromMobile("multi").then((value) {
if (value != null) {
value.paths.forEach((element) {
images.add(File(element));
});
// images = value.paths.map((path) => File(path)).toList();
}
});
setState(() {});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(...,
body: Container(
height: double.infinity,
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(bottom: 50),
child: Container(
child: ListView.builder(
itemCount: 10,
reverse: true,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (ctx, idx) {...
///...
),
),
),
///This is the part that hides behide the keyboard when it appears which i want to show on top
Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: white,
border: Border(
top: BorderSide(
color: grey[400],
width: .7,
),
bottom: BorderSide(
color: grey[400],
width: .7,
)),
),
constraints: BoxConstraints(maxHeight: 160), //This is the box contraints
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
(images.length < 1)
? SizedBox(height: 0)
: Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: ScrollPhysics(),
padding: EdgeInsets.symmetric(
vertical: 7, horizontal: 10),
itemCount: images.length,
itemBuilder: (ctx, idx) {
return Container(
///... This is to show a image from file width a height of 100
);
},
),
),
Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: grey[300],
width: .5,
)),
),
child: Row(children: [
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.image),
onPressed: () => getMultiFile(),
color: primary,
),
),
Flexible(
child: Container(
child: TextFormField(
//controller: messageEditingController,
style: TextStyle(color: nBlack, fontSize: 15.0),
decoration: InputDecoration.collapsed(
hintText: 'Type a message',
hintStyle: TextStyle(color: grey),
),
onFieldSubmitted: (value) {},
),
),
),
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.send),
onPressed: () {},
color: primary,
),
),
]),
),
],
),
),
)
],
),
),
resizeToAvoidBottomInset: false,
));
}
}
Please how can I make it work cause i have checked different pages still does give me what i want. I also tried this [answer][1]
[1]: https://stackoverflow.com/a/49715952/14650702 which worked but the animation was terrible

You can change resizeToAvoidBottomInset: ture, for scaffold.
it will shrink the whole scaffold when keyboard is opened.

I use another way. resizeToAvoidBottomInset: true and do some changes for lifting widgets top of keyboard.
bottom = MediaQuery.of(context).viewInsets.bottom;
Scaffold(
resizeToAvoidBottomInset: ture,
body: SingleChildScrollView(
reverse:true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: ...
)));
if you decrease space from keyboard to last widget use MediaQuery.of(context).viewInsets.bottom/2 e.x.

Related

how to control the slidingUpPanel draggable

i want a slidingUpPanel similar to YouTube comments section. that not open with the scrolling of the content but open and close only from the drag handle by tap or by swipe up/down).
the drag handle is the top section of the slidingUpPanel :
so the draggable should happen only from this drag handle not from the whole body. (you can try the code below to know what i mean)
it means if i scroll the body(the listView builder) the slidingUpPanel keep its place (either open or closed) until i swip it from the drag handle.
my current code:
PanelController panelController = PanelController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
SlidingUpPanel(
controller: panelController,
maxHeight: MediaQuery.of(context).size.height * .9,
minHeight: MediaQuery.of(context).size.height * .7,
borderRadius: BorderRadius.vertical(top: Radius.circular(40.0)),
panelBuilder: (controller) => Stack(
alignment: Alignment.topCenter,
children: [
GestureDetector(
onTap: () {
panelController.isPanelOpen
? panelController.close()
: panelController.open();
},
child: Container(
color: Colors.transparent,
height: 36.0,
width: MediaQuery.of(context).size.width,
child: Center(
child: Container(
width: 46.77,
height: 4.0,
decoration: BoxDecoration(color: Colors.grey),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 40.0),
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
controller: controller,
padding: EdgeInsets.zero,
itemCount: 20,
itemBuilder: (context, index) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 70.0,
color: Colors.red,
),
),
],
);
}),
),
],
)),
],
),
));
}

GridView.count() doesn't scroll - Flutter

I want the Card widgets to scroll horizontally, but it's not working. I've tried and changed GridView to ListView.
Adding physics is not helping either.
Here's the code:
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Expanded(
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: SizeConfig.blockSizeVertical * 2),
child: (Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Names',
style: Theme.of(context).textTheme.headline6,
),
InkWell(
onTap: () {},
child: Row(children: [
Text('show more',
style: Theme.of(context).textTheme.caption),
const Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(
Icons.keyboard_arrow_left_sharp,
size: 20,
),
),
]),
),
],
)),
),
FutureBuilder<DataModel>(
future: InfoAPI('assets/itemsData.json').getDataLocally(context),
builder: (context, snapshot) {
final data = snapshot.data;
final List<String> list = getnames(data);
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).primaryColor,
),
height: SizeConfig.blockSizeVertical * 20,
// width: double.infinity,
child: GridView.count(
crossAxisCount: 1,
padding: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 10.0),
scrollDirection: Axis.horizontal,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: List.generate(list.length, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
//clipBehavior: Clip.antiAlias,
color: Theme.of(context).cardColor,
child: Center(
child: Text(
list[index],
style: Theme.of(context).textTheme.bodyText1,
)));
},
)),
);
})
],
),
);
}```
So, after long research I discovered that the 'horizontal scrolling' is working just fine on mobile, the problem was because I used chrome.
You can refer to [Horizontal listview not scrolling on web but scrolling on mobile] for more information.
Try wrapping your ListView/GridView with a Flexible Widget. Also Youve set physics to NeverScrollableScrollPhysics() so change it to some other scroll physics(like AlwaysScrollableScrollPhysics()) if you want it to be scrollable

How can i prevent my keyboard from hiding my widgets in a ScrollableView

Am implementing this plugin here and in the body i create a screen that uses SingleChildScrollView to show some text fields,
Like the documentation says
Body: The Widget that lies underneath the sliding panel. This Widget
automatically sizes itself to fill the screen.
The problem is that when I give focus to one of the text fields the keyboard appears and hides what I am writing,
I use the plugin passing a the widget i want to show behind
SlidingUpPanel(
...
body: Padding(
padding: EdgeInsets.only(top: 160 + padding!.top),
child: behindWidget,
),
...
)
then this
I was trying to enclose my SingleChildScrollView inside a scaffold to use this: resizeToAvoidBottomInset: true, but that doesn't seem to make any difference, does anyone have any idea what I can do? and if there is a way to do it directly from the TextFormField would it be better?
I also have to say that I am using a DefaultTabController and in the first tab I enclose my SingleChildScrollView
like this:
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Padding(
padding: EdgeInsets.only(top: 10),
child: DefaultTabController(
initialIndex: 0,
length: myTabs.length,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
bottom: TabBar(
labelColor: Colors.black,
labelStyle: smallTextBoldBlack,
unselectedLabelColor: unselectedColor,
unselectedLabelStyle: smallTextUnselectedSecondary,
indicatorColor: Colors.black,
controller: _tabController,
tabs: myTabs,
),
title: Text(
'Create a new Event',
style: subTitle,
),
),
body: TabBarView(
physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
controller: _tabController,
children: [
_buildCreateEventView(),
Text("b"),
],
),
),
),
),
);
}
_buildCreateEventView()
Widget _buildCreateEventView() {
return ExpandableCalendar(
eventList: [],
padding: EdgeInsets.only(top: 20),
onDateSelected: (DateTime selectedDate) => {
if (this.mounted)
setState(() {
currentDate = selectedDate;
})
},
behindWidget: Scaffold(
resizeToAvoidBottomInset: true,
body: Container(
padding: EdgeInsets.only(left: 10, top: 20, right: 10, bottom: 10),
color: Colors.white,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width,
maxHeight: MediaQuery.of(context).size.height,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(top: 10, bottom: 10, left: 5),
child: TextFormField(
controller: eventNameController,
decoration: InputDecoration(
border: UnderlineInputBorder(),
labelText: 'Enter Event Summary',
),
),
),
Container(
padding: EdgeInsets.only(top: 10, bottom: 10, left: 5),
child: TextFormField(
controller: eventDescriptionController,
decoration: InputDecoration(
border: UnderlineInputBorder(),
labelText: 'Enter Event Description',
),
),
),
],
),
),
),
),
));
}
I'm not sure how your ExpandableCalendar class works but I suspect it's what is preventing Flutter from resizing the Scaffold body to move the text fields above the keyboard. If you try temporarily removing ExpandableCalendar and you see the widgets moving above your keyboard that should give you a clue to the underlying issue.
Add One more Container inside SingleChildScrollView and remove Scaffold
Container
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
SingleChildScrollView
Container
ConstrainedBox

List menu scrolling without IgnorePointer

I created a menu list with GridView. But when I scroll, it fail because scroll inside listview hold parent element to scroll like this image
My issue is gone when I try to wrap my GridView inside IgnorePointer. But if I use IgnorePointer it is not allow me to click / tap my menu item.
How the best way to fix my issue?
My code (without IgnorePointer)
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 10.0, bottom: 10.0),
width: MediaQuery.of(context).size.width,
child: GridView.count(
shrinkWrap: true,
crossAxisCount: 4,
children: List.generate(
menuItems.length,
(index) {
return Column(
children: <Widget>[
InkWell(
onTap: () {
showShortToast("Menu clicked " + index.toString());
},
child: Container(
width: 70.0,
height: 70.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
border: Border.all(color: Colors.grey[300]),
),
child: Center(
child: Image.asset(menuItems[index]["image"]),
),
),
),
Expanded(
child: Text(
menuItems[index]["text"],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13.0,
),
),
),
],
);
},
),
),
);
}
If you want to disable the scroll in the grid view you can do as follows:
child: GridView.count(
physics: NeverScrollableScrollPhysics(), //Add physics
shrinkWrap: true,
crossAxisCount: 4,
...

How to solve ListView.builder bottom overflow issue?

I'm having the same issue that is outlined here. I've tried all of the solutions provided and I'm still getting an error "RenderFlex overflowed by x pixels on the bottom". I don't have any widgets underneath the custom ListView Builder. I'm really at a loss here.
Widget build(BuildContext context) {
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new GradientAppBar("Twitter"),
new Container(
child: Flexible(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 10.0, left: 10.0),
child: UserInfoHeader(userinfo)
),
PagewiseListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(),
pageSize: 200,
itemBuilder: (context, TwitterCardContent entry, _) {
return TwitterCard(entry);
},
pageFuture: (pageIndex) {
return getStatuses(userinfo.screenName);
},
)
],
),
),
),
],
);
}
And here is the contents of each List item.
Widget build(BuildContext context) {
return new Card(
//elevation: 8.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.circular(25.0)
),
child: ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
leading: Container(
padding: EdgeInsets.only(right: 12.0),
decoration: new BoxDecoration(
border: new Border(
right: new BorderSide(width: 1.0, color: Colors.white54)
)
),
child: notchecked,
),
title: Text(
statusCard.timeStampString,
style: Theme.TextStyles.buttonText,
),
subtitle: Text(
statusCard.text,
style: Theme.TextStyles.contentCardText,
),
trailing: delete,
),
),
);
}
Column widget doesn't scroll and you have that widget as your parent widget and PageListView as a child inside it.
Instead, replace your parent Column widget with ListView that should resolve renderflow exception.
Wrap your listview builder with expanded widget.
just to add an example to Dave's answer
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: 5,
itemBuilder: (context, index) {
return Container();
}
Problem is that your ListView is inside a Column which has fixed height and can't be scroll whereas listview scrolls. I am not sure but changing Column a listview itself or using Expanded/Flexible with Column could workOut.