Flutter扩展/占据TextFormField以填充屏幕的其余部分

wgmfuz8q  于 2023-02-05  发布在  Flutter
关注(0)|答案(7)|浏览(189)

我有一个包含一些TextFormField的窗体,我想展开最后一个TextFormField以占据屏幕的其余部分。最后一个TextFormField可以包含多行文本。
我还没能做到这一点,并尝试了SizedBox.expand()Expanded小部件,但没有运气。

以下是当前代码:

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,
                    ),
                  ),
                ]
              ),
            ),
          ),
        ],
      ),
    ),
    );
  }
}
wtlkbnrh

wtlkbnrh1#

我编辑了你的代码一点。但是它没有工作。请参考下面的代码。我会尝试解释我的理解下面的代码。

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",
                      ),
                    ),
                  ),
                ),
              ]),
            )),
          ],
        ),
      ),
    );
  }
}

我用你的代码检查了视图。TextFormField里面的TextField没有占据屏幕的其余部分。所以我编辑了TextField来占据屏幕的其余部分。上面的代码就是这么做的。请看检查过的视图x1c 0d1x
但是有一个InputDecorator(我们的TextField的子元素)可以绘制边界线,在我们的例子中,它是基于内容来绘制边界线的。
可能的解决方法包括:

  1. maxLines = null,它将TextField作为内容组增长。但初始视图将是一行。
    1.给定固定的maxLines(如10或20),看起来像是占据了屏幕。但它不是动态的(不根据屏幕大小/屏幕方向而改变)
pw136qt2

pw136qt22#

我找到了解决方案,也许它可以帮助别人。你可以创建容器或另一个小部件与边框一样,如TextField,并使其扩展到整个屏幕和以上的堆栈小部件把TextField与maxLines:空且无边框。
[EDIT]它也可以在没有Stack小部件的情况下工作。以下是我的代码

Expanded(
                  child: Material(
                    borderRadius: BorderRadius.circular(10),                      
                    color: Colors.white,
                    child: TextField(                         
                      decoration: InputDecoration(
                        border: InputBorder.none,  
                        hintText: "Description",                         
                      ),
                      keyboardType: TextInputType.multiline,
                      maxLines: null,
                    ),
                  ),
                ),
hs1rzwqc

hs1rzwqc3#

您也可以在initState()中使用addPostFrameCallback渲染小部件后设置contentPadding,但您必须根据所有上述小部件的位置和高度手动计算新的高度。
示例:

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",
                      ),
                    ),
                  ),
                ]),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

qeeaahzv

qeeaahzv4#

我知道这有点晚了,但是答案已经在here上发布了。

TextField(
  keyboardType: TextInputType.multiline,
  maxLines: whatever,
)
7vux5j2d

7vux5j2d5#

文本表单字段包含expands属性。

Expanded(
  child: TextFormField(
    //...
    maxLines: null,
    expands: true,
)),

expands属性设置为true时,必须将maxLines设置为null。然后,要使其工作,请将TextFormField Package 在Expanded中。

r1zk6ea1

r1zk6ea16#

它非常简单

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,
    ),
  )
eeq64g8w

eeq64g8w7#

expands: true,

解决了您的问题:)下面是扩展文本字段的代码:

TextField(
              maxLines: null,
              expands: true,
              textAlignVertical: TextAlignVertical.top,
              keyboardType: TextInputType.multiline)

相关问题