Update
Added Minimal code
I want to display long text in scrollview.
Upto redline text is scrollable
I tried:
Using flexible :: Same Result
Wraping in Container :: It makes text full screen and non scrollable
Code
new Expanded(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
'Very Long text',
style: TextStyle(color: Colors.black, fontSize: 24),
)),
),
If i try to increase flex property it starts overlapping with upper widget
Thankyou
Full Code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
backgroundColor: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Color(0xff010409),
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: TextField(
// controller: _uri,
decoration: InputDecoration(
hintText: 'Search', prefixIcon: Icon(Icons.search)),
),
actions: <Widget>[
FlatButton(
textColor: Colors.white,
onPressed: () {
},
child: Icon(Icons.search),
shape: CircleBorder(side: BorderSide(color: Colors.transparent)),
),
],
),
body: SafeArea(
child: Column(children: <Widget>[
Flexible(
child: Text(
'abc',
style: TextStyle(
color: Color(0xff58a6ff), fontWeight: FontWeight.bold, fontSize: 30),
)),
new Expanded(
flex:2,
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
'Big String',
style: TextStyle(color: Colors.white, fontSize: 24),
)),
),
])),
);
}
}
This snipped of code works fine for me
UPDATED:
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Color(0xff010409),
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: TextField(
// controller: _uri,
decoration: InputDecoration(
hintText: 'Search', prefixIcon: Icon(Icons.search)),
),
actions: <Widget>[
FlatButton(
textColor: Colors.white,
onPressed: () {},
child: Icon(Icons.search),
shape: CircleBorder(side: BorderSide(color: Colors.transparent)),
),
],
),
body: SafeArea(
child: Column(children: <Widget>[
//Removed Flexible Widget
Text(
'abc',
style: TextStyle(
color: Color(0xff58a6ff),
fontWeight: FontWeight.bold,
fontSize: 30),
),
new Expanded(
// flex: 2, //commented flex here for taking the whole available space.
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
"""A Long Long String Here...""",
style: TextStyle(color: Colors.white, fontSize: 24),
)),
),
])),
);
}
}
In Above Code Replace A very Long long String with your long Text
As #AK-23 Pointed out that, Are you sure you need Expanded widget above the SingleChildScrollView ?
If Yes then Paste your full Code, So that we can Figure Out the issue.
EDITED:
I have Removed the Flexible widget from the text, and commented the flex widget for the Expanded widget, and The code started working.
Wrapping the Text widget with Column worked out for me, like this:
...
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children <Widget> [
Text('Very Long text',
style: TextStyle(color: Colors.black, fontSize: 24),
),
]
)
...
I'm not sure whether or not you need the Expanded above the SingleChildScrollView
Related
I am trying to get the customer number through TextField and just to test displaying it over the next screen, but nothing appears.
Widget build(BuildContext context) {
final searchRecordField = TextFormField(
autofocus: false,
keyboardType: TextInputType.number,
controller: customerNumber,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.phone),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Enter Customer Number",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
Code for next screen.
return Scaffold(
body: Container(
child: (
Text("Showing Results for ${customerNumber.text.toString()}",
style: TextStyle(
color: Colors.black12, fontSize: 24, fontWeight: FontWeight.bold),
),
),
),
);
It shows "showing results for" but not the number I entered in the previous screen.
From the documentation,
You can accomplish this task using the arguments parameter of the Navigator.pushNamed() method. Extract the arguments using the ModalRoute.of() method or inside an onGenerateRoute() function provided to the MaterialApp or CupertinoApp constructor.
Below is a simple prototype that should do the trick. Check the screenshots and the DartPad prototype:
1st page
2nd page
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/home',
routes: {
'/home': (context) => const HomePage(),
'/next': (context) => NextPage(
ModalRoute.of(context)!.settings.arguments as String,
),
},
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final customerNumber = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pass Args Between Routes Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(20),
child: TextFormField(
style: Theme.of(context).textTheme.headline4,
autofocus: false,
keyboardType: TextInputType.number,
controller: customerNumber,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.phone),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Enter Customer Number",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
ElevatedButton(
onPressed: () => Navigator.pushNamed(context, '/next',
arguments: customerNumber.text),
child: const Text(
'Next',
style: TextStyle(fontSize: 30),
))
],
),
),
);
}
}
class NextPage extends StatefulWidget {
final String customerNumber;
const NextPage(this.customerNumber, {Key? key}) : super(key: key);
#override
State<NextPage> createState() => _NextPageState();
}
class _NextPageState extends State<NextPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pass Args Between Routes Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Text(
widget.customerNumber,
style: const TextStyle(fontSize: 30),
),
),
],
),
),
);
}
}
You have to pass the data from the initial screen to the new screen, so that you can render the data.
Here's flutter resource on how to pass data between 2 screens.
https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments
What i have ? :
Now i can enter text into blue section, after click on it keyboard shows and every widget adjust to another (by mainAxisAlignment: MainAxisAlignment.spaceAround).
What i want to have ? :
I want the same thing as i have but i want to be able to click on red section to show up keyboard. (while keeping adjusting widgets)
shortened version of
main.dart :
import 'package:flutter/material.dart';
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
child: const TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter Word",
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width,
child: const CustomPaint(
// foregroundPainter: LinePainter(),
),
),
const Text(
"Nie ma takowego słowa",
textAlign: TextAlign.center,
),
])));
}
To do this, you can wrap your TextField in an Expanded widget, which will expand to fill its parent and then set the expanded parameter of the TextField to true and maxLines to null. This will allow the TextField to expand to match its parent's (the Expanded widget's) height:
Expanded(
child: TextField(
expands: true,
maxLines: null,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
),
)
If you do not want your textfield itself to expand, you need to use a
Expanded(
child: GestureDetector(
child: Center(child: TextField(focusNode: _focusNode))
),
)
and use the focusNode of the TextField to request focus for it when tapping the GestureDetector. Example here: https://docs.flutter.dev/cookbook/forms/focus. This will require using a StatefulWidget, as the focusNode is long-lived state.
final code (not shortened)
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:xmltranslator/painter.dart';
import 'package:xmltranslator/xmlreader.dart';
void main() {
runApp(const MyApp());
WidgetsFlutterBinding.ensureInitialized();
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage("text"),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage(String text, {Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
final _searchValue = TextEditingController();
String _typedText = "finding txt";
String _translatedText1 = "translation";
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
getXmlFile(context, _searchValue.text, context);
super.initState();
myFocusNode = FocusNode();
}
late FocusNode myFocusNode;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 77, 77, 77),
appBar: AppBar(
centerTitle: true,
backgroundColor: const Color.fromARGB(255, 47, 47, 47),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RichText(
text: TextSpan(children: [
TextSpan(
text: "T r a n ",
style: GoogleFonts.overpass(
fontWeight: FontWeight.bold, fontSize: 30)),
TextSpan(
text: " S l a t e",
style: GoogleFonts.overpass(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 30)),
]),
),
],
),
elevation: 20,
),
body: SafeArea(
child: Column(children: [
Expanded(
child: TextField(
textAlignVertical: TextAlignVertical.center,
style: GoogleFonts.overpass(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 23),
controller: _searchValue,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
hintText: "Enter Word",
),
onEditingComplete: () async {
String xmlString = await DefaultAssetBundle.of(context)
.loadString("assets/test.xml");
final _translatedText2 =
await getXmlFile(context, _searchValue.text, xmlString);
setState(() {
_typedText = _searchValue.text;
});
if (xmlString.contains(_typedText)) {
setState(() {
_translatedText1 = _translatedText2.first.toString();
});
} else {
setState(() {
_translatedText1 = "Nie ma takowego słowa";
});
print("wartosc po funkcji:$_translatedText2");
}
},
),
),
SizedBox(
width: MediaQuery.of(context).size.width,
child: CustomPaint(
foregroundPainter: LinePainter(),
),
),
Expanded(
child: Text(_translatedText1,
textAlign: TextAlign.center,
style: GoogleFonts.overpass(
color: Colors.red,
fontSize: 30,
)),
),
])));
}
}
I am new to Flutter and I need your help for solving the first issue.
This is the main.dart file:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
backgroundColor: Colors.white,
),
home: MyHomePage(title: 'Flutter Login'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
final emailField = TextField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Email",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
final passwordField = TextField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Contraseña",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
final loginButon = Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {},
child: Text("Entrar",
textAlign: TextAlign.center,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)),
),
);
return Scaffold(
body: SingleChildScrollView(
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(66.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 185.0,
child: Image.asset(
"assets/logo_capenergy.png",
fit: BoxFit.contain,
),
),
SizedBox(height: 45.0),
emailField,
SizedBox(height: 25.0),
passwordField,
SizedBox(
height: 35.0,
),
loginButon,
SizedBox(
height: 15.0,
),
],
),
),
),
),
)
);
}
}
And this is a screenshot from the Flutter app:
I am not able to remove or hide the bottom background darker zone.
Don't put your color in the Container but in the Scaffold:
Scaffold(
backgroundColor: Colors.white
...
as below i try to add a TextFormFiled and after adding it the error A renderFlex overFlowed is occure :
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text('Rate the order !', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(starCount, (index)=>buildStar(context, index)),
),
Padding(
padding: EdgeInsets.all(10),
child: Form(child:TextFormField(
decoration: (InputDecoration(
labelText: 'add your notes'
)),
textInputAction: TextInputAction.done,
)),
)
],
);
Wrap the Column in a SingleChildScrollView.
Working sample on DartPad:
https://dartpad.dev/b6409e10de32b280b8938aa75364fa7b
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Material(child:
SingleChildScrollView(child:
Column(
children: <Widget>[
Text('Rate the order !', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(10, (index)=>Icon(Icons.star)),
),
SizedBox(height: 10,),
Column(
mainAxisAlignment: MainAxisAlignment.center,
// add many children just to overflow on the bottom
children: List.generate(100, (index)=>Icon(Icons.video_call)),
),
Padding(
padding: EdgeInsets.all(10),
child: Form(child:TextFormField(
decoration: (InputDecoration(
labelText: 'add your notes'
)),
textInputAction: TextInputAction.done,
)),
)
],
),),);
}
}
Put the Column as the child of SingleChildScrollView
this worked perfectly, check it out. See code below:
import 'package:flutter/material.dart';
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text('Rate the order !', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
SizedBox(height: 10,),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(starCount, (index)=>buildStar(context, index)),
),
),
Padding(
padding: EdgeInsets.all(10),
child: Form(child:TextFormField(
decoration: (InputDecoration(
labelText: 'add your notes'
)),
textInputAction: TextInputAction.done,
)),
)
],
);
I hope it helps.
Give column or your list inside of row a fixed height. use Container or any other widget
I have a form with some TextFormField, and I want to expand the last TextFormField to occupy the rest of the screen. This last TextFormField can have multiple lines of text.
I haven't been able to achieve this, and have tried SizedBox.expand() and the Expanded widget, but no luck.
Below is the current code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"What is this new classroom?"
),
SizedBox(height: 8.0,),
Expanded(
child: Form(
key: _formKey,
child: ListView(
padding: EdgeInsets.all(8.0),
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Classroom Name",
hintText: "What's name of the new classroom?",
),
)
),
SizedBox(height: 8.0,),
Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Description",
hintText: "Description of the new classroom",
),
//maxLines: 5,
),
),
]
),
),
),
],
),
),
);
}
}
I edited your code a bit. But it didn't work. Please refer the below code. I will try to explain my understanding below the code.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("What is this new classroom?"),
SizedBox(
height: 8.0,
),
Expanded(
child: Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Classroom Name",
hintText: "What's name of the new classroom?",
),
)),
SizedBox(
height: 8.0,
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Description",
hintText: "Description of the new classroom",
),
),
),
),
]),
)),
],
),
),
);
}
}
I inspected the view with your code. TextField which is inside TextFormField is not occupying the rest of the screen. So I edited to have TextField to have the rest of the screen. The above code does that. See the inspected view
But the there is InputDecorator (which is child of our TextField) which draws the border line. In our case, it draws the border line based on content.
Possible workarounds could be:
maxLines = null which will grow the TextField as the content groups. But initial view will be one line.
Give fixed maxLines (as 10 or 20) which might look like occupying the screen. But it is not dynamic(doesn't change based on screen size / screen orientation)
I found solution, maybe it can help someone. You can create Container or another widget with border same like TextField and make it expanded to fill whole Screen and above that with Stack widget put TextField with maxLines: null and without border.
[EDIT] It works also without Stack widget. Here is my code
Expanded(
child: Material(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Description",
),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
),
You can also set contentPadding after widgets are rendered using addPostFrameCallback inside initState().
But you will have to calculate new height manually based on positions and heights of all above widgets.
Example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _tffKey1 =
GlobalKey();
final _tffKey2 = GlobalKey();
final _scaffoldKey = GlobalKey();
final _textKey = GlobalKey();
double _height = 0;
//Set callback that will be called after widgets are rendered.
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final RenderBox scaffoldKeyBox = _scaffoldKey.currentContext.findRenderObject();
final RenderBox tffBox = _tffKey1.currentContext.findRenderObject();
final RenderBox textBox = _textKey.currentContext.findRenderObject();
final tffPos = tffBox.localToGlobal(Offset.zero);
final textPos = textBox.localToGlobal(Offset.zero);
//Calculate widget's height.
_height = (scaffoldKeyBox.size.height -
(tffBox.size.height + tffPos.dy) -
(textBox.size.height + textPos.dy));
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"What is this new classroom?",
key: _textKey,
),
SizedBox(
height: 8.0,
),
Expanded(
child: Form(
key: _formKey,
child:
ListView(padding: EdgeInsets.all(8.0), children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
key: _tffKey1,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Classroom Name",
hintText: "What's name of the new classroom?",
),
)),
Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: TextFormField(
key: _tffKey2,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 8, top: _height), // Set new height here
border: OutlineInputBorder(),
labelText: "Description",
hintText: "Description of the new classroom",
),
),
),
]),
),
),
],
),
),
);
}
}
I know it's a litte bit late, but the answer has been posted here.
You just need the following
TextField(
keyboardType: TextInputType.multiline,
maxLines: whatever,
)
expands: true,
solves your problem:) Here is the code for the expanded text field:
TextField(
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.top,
keyboardType: TextInputType.multiline)
TextFormField contains expands property.
Expanded(
child: TextFormField(
//...
maxLines: null,
expands: true,
)),
When you set expands property to true, you must set maxLines to null. Then, to make it work, wrap TextFormField inside Expanded.
it is very simple
TextFormField(
expands: true, // add this line
minLines: null, // add this line
maxLines: null, // add this line
decoration: InputDecoration(
// if you want to change text form field background color
// add this two lines
fillColor: Theme.of(context).colorScheme.background,
filled: true,
),
)