I have a textfield widget that allows user to enter multiple lines, but after entering few lines, got overflow error as shown below.
This happened because whenever there is new line, the textfield height increases and pushed down the keyboard. This is before entering new line.
I used resizeToAvoidBottomInset: false,
to solve the problem where keyboard covers textfield but this doesn't seem to solve the problem above.
Is there any way I can push the textfield up after entering new line as shown below so that the keyboard the textfield won't overflow the keyboard?
This is my code
import 'dart:async';
import 'package:flutter/material.dart';
class Detail extends StatefulWidget {
const Detail({Key? key}) : super(key: key);
@override
State<Detail> createState() => _DetailState();
}
class _DetailState extends State<Detail> {
final ScrollController scrollCtrl = ScrollController();
bool isScrolled = false;
bool isLoading = false;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final bottom = MediaQuery.of(context).viewInsets.bottom;
AppBar appbar = AppBar(
backgroundColor: Colors.transparent,
title: const Text('Approval Detail'),
);
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
scrollCtrl.addListener(() {});
scrollCtrl.position.isScrollingNotifier.addListener(() {
if (!scrollCtrl.position.isScrollingNotifier.value) {
setState(() {
isScrolled = false;
});
} else {
setState(() {
isScrolled = true;
});
}
});
});
return Container(
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/bg_home.png'),
fit: BoxFit.fill,
),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
// resizeToAvoidBottomPadding: false,
backgroundColor: Colors.transparent,
appBar: appbar,
body: Stack(
children: [
SingleChildScrollView(
controller: scrollCtrl,
reverse: true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 200),
child: Text("Detail")),
Container(
height: 25,
color: columnColor,
),
],
),
),
),
IndexedStack(
index: isScrolled
? 0
: 1, // switch between Foo and Bar based on condition
children: [
Container(),
Positioned(
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Align(
alignment: Alignment.bottomCenter, child: BottomWidget()),
)),
],
)
],
),
),
);
}
}
This is my BottomWidget
import 'package:flutter/material.dart';
class BottomWidget extends StatefulWidget {
BottomWidget({
Key? key,
}) : super(key: key);
@override
State<BottomWidget> createState() => _BottomWidgetState();
}
class _BottomWidgetState extends State<BottomWidget> {
@override
Widget build(BuildContext context) {
return Container(
height: 180,
width: double.maxFinite,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey[300]!,
offset: const Offset(0.0, 2.5),
blurRadius: 1.0,
),
const BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 0.0),
blurRadius: 1.0,
),
],
color: Colors.white,
borderRadius:
const BorderRadius.vertical(top: Radius.circular(20.0))),
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
child: SizedBox(
width: double.maxFinite,
// height: 45,
child: Row(
children: [
Flexible(
flex: 9,
child: TextField(
minLines: 1,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: BorderSide(color: Color(0xFFD6DDE1))),
focusedBorder: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(20.0),
borderSide: BorderSide(color: cbossBlue),
),
filled: true,
hintStyle: TextStyle(color: Color(0xFFD6DDE1)),
hintText: "Add note here",
fillColor: Colors.white70),
),
),
Flexible(
flex: 1,
child: IconButton(
icon: Icon(Icons.fullscreen),
onPressed: () {
},
),
)
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
child: Container(
width: double.maxFinite,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Flexible(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(right: 5),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: cbossBlue),
borderRadius: BorderRadius.all(Radius.circular(2))),
height: 50,
child: InkWell(
onTap: () {
},
child: Center(
child: Text('Reject',
style: TextStyle(
color: cbossBlue,
fontWeight: FontWeight.bold))),
),
),
),
),
Flexible(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(right: 5),
child: Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(2))),
height: 50,
child: InkWell(
onTap: () {
},
child: const Center(
child: Text(
'Approve',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white),
)),
),
),
),
),
],
),
),
),
],
),
);
}
}
CodePudding user response:
The most common way to fix it is to wrap your form with SingleChildScrollView
widget.
CodePudding user response:
Share your widget tree so we can give you best solution.
for now, if you have a Column
as root widget, replace it with Listview
. this will fix your problem and make view scrollable when keyboard opened.
the widget tree will lock like something like this :
ListView(
children:[
widget1(),
widget2(),
.....
]
)
CodePudding user response:
Edit
I tried such solution for you. I think it will be simpler and easier to edit. I will shoot an emulator video and add it soon, at that time you can think of the solution. I hope it was able to answer your question.
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: [
Expanded(
child: Stack(
children: [
ListView(
children: [
Column(
children: const [
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
Text("Foo"),
],
),
],
)
],
)),
TextField(
minLines: 1,
keyboardType: TextInputType.multiline,
maxLines: 5,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: const BorderSide(color: Color(0xFFD6DDE1))),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: const BorderSide(color: Colors.blue),
),
filled: true,
hintStyle: TextStyle(color: Color(0xFFD6DDE1)),
hintText: "Add note here",
fillColor: Colors.white70),
),
ElevatedButton(onPressed: () {}, child: Text("Floating Texts")),
],
),
),
);
}
}
I think you wanted something like this :) https://i.imgur.com/spxpZsZ.mp4