Flutter Expand / Occupy TextFormField для заполнения остальной части экрана - PullRequest
0 голосов
/ 28 октября 2018

У меня есть форма с некоторым TextFormField, и я хочу расширить последний TextFormField, чтобы занять остальную часть экрана.Этот последний TextFormField может содержать несколько строк текста.

Мне не удалось этого добиться, и я пробовал SizedBox.expand() и виджет Expanded, но не повезло.

enter image description here

Ниже приведен текущий код:

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

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вы также можете установить contentPadding после визуализации виджетов, используя addPostFrameCallback внутри initState().Но вам придется вычислять новую высоту вручную, основываясь на положениях и высотах всех вышеперечисленных виджетов.

Пример:

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

example

0 голосов
/ 14 июня 2019

Я знаю, что немного поздно, но ответ был опубликован здесь .Вам просто нужно следующее

TextField(
  keyboardType: TextInputType.multiline,
  maxLines: whatever,
)
0 голосов
/ 28 октября 2018

Я немного отредактировал твой код.Но это не сработало .Пожалуйста, ознакомьтесь с кодом ниже.Я постараюсь объяснить мое понимание под кодом.

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

Я проверил вид с вашим кодом.TextField внутри TextFormField не занимает остальную часть экрана.Поэтому я отредактировал, чтобы иметь TextField, чтобы остальная часть экрана.Код выше делает это.Смотрите проверенный вид enter image description here

Но есть InputDecorator (который является дочерним для нашего TextField), который рисует границу.В нашем случае она рисует граничную линию на основе содержимого.

Возможные обходные пути могут быть:

  1. maxLines = null, которые увеличат TextField как группы содержимого.Но первоначальный вид будет одной строкой.
  2. Дайте фиксированный maxLines (как 10 или 20), который может выглядеть как занимающий экран.Но он не динамический (не изменяется в зависимости от размера экрана / ориентации экрана)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...