布局问题:具有TextField键盘的TabBarView溢出

时间:2020-08-10 09:40:07

标签: flutter dart flutter-layout

我正在尝试实现特定的设计,正如标题所述,我在构建版面时遇到了问题。

当我在TextField内敲击时,键盘会自动打开并产生溢出。

屏幕截图

代码

deals_edition_page.dart

import 'package:flutter/material.dart';
import 'package:myuca/ui/manager/deals/edition_informations_tab.dart';

class DealsEditionPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DealsEditionPageState();
}

class _DealsEditionPageState extends State<DealsEditionPage> {
  MemoryImage _image;

  Widget _buildAppbar() {
    return AppBar(
      elevation: 0,
      leading: IconButton(
        icon: Icon(Icons.close),
        onPressed: () => Navigator.pop(context),
      ),
      title: Text(/* random String */),
      actions: [
        IconButton(
          icon: Icon(Icons.check),
          onPressed: () => Navigator.pop(context),
        ),
      ],
    );
  }

  Widget _buildHeaderTabBar() {
    return SliverAppBar(
      automaticallyImplyLeading: false,
      expandedHeight: 224,
      floating: true,
      elevation: 0,
      flexibleSpace:
          FlexibleSpaceBar(background: Image.memory(_image.bytes, fit: BoxFit.cover)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppbar(),
      body: DefaultTabController(
        length: 2,
        child: CustomScrollView(
          slivers: <Widget>[
            _buildHeaderTabBar(),
            SliverToBoxAdapter(
              child: TabBar(
                indicatorWeight: 2,
                tabs: [
                  Tab(text: 'Informations'),
                  Tab(text: 'Informations'),
                ],
              ),
            ),
            SliverFillRemaining(
              child: Column(
                children: [
                  Expanded(
                    child: TabBarView(
                      children: [
                        EditionInformationsTab(),
                        Center(child: Text("Tab 2")),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

edition_informations_tab.dart

import 'package:flutter/material.dart';
import 'package:myuca/extensions/extensions.dart' show WidgetModifier;

class EditionInformationsTab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _EditionInformationsTabState();
}

class _EditionInformationsTabState extends State<EditionInformationsTab> {
  final _list1 = <String>['Culture', 'Test'];
  final _list2 = <String>['Etablissement', 'Test 1', 'Test 2'];

  List<DropdownMenuItem<String>> _menuItemsGenerator(List<String> values) =>
      values
          .map<DropdownMenuItem<String>>((e) => DropdownMenuItem<String>(
                value: e,
                child: Text(e),
              ))
          .toList();

  @override
  Widget build(BuildContext context) {
    return Form(
      child: Column(
        children: [
          DropdownButtonFormField<String>(
            value: _list1.first,
            decoration: InputDecoration(
                border:
                    OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
            items: _menuItemsGenerator(_list1),
            onChanged: (_) {},
          ).padding(EdgeInsets.only(bottom: 24)),
          DropdownButtonFormField(
            value: _list2.first,
            decoration: InputDecoration(
                border:
                    OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
            items: _menuItemsGenerator(_list2),
            onChanged: (_) {},
          ).padding(EdgeInsets.only(bottom: 24)),
          TextFormField(
            maxLength: 30,
            decoration: InputDecoration(
                labelText: "Nom de l'offre",
                border:
                    OutlineInputBorder(borderRadius: BorderRadius.circular(4))),
          ),
        ],
      ),
    ).padding(EdgeInsets.only(
        top: 16, left: 16, right: 16));
  }
}

关于显示键盘时如何避免这种溢出的任何想法?

1 个答案:

答案 0 :(得分:0)

您可以在下面复制粘贴运行完整代码
您可以用_EditionInformationsTabState包裹SingleChildScrollView

class _EditionInformationsTabState extends State<EditionInformationsTab> {
  ...

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

class DealsEditionPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DealsEditionPageState();
}

class _DealsEditionPageState extends State<DealsEditionPage> {
  MemoryImage _image;

  Widget _buildAppbar() {
    return AppBar(
      elevation: 0,
      leading: IconButton(
        icon: Icon(Icons.close),
        onPressed: () => Navigator.pop(context),
      ),
      title: Text("demo"),
      actions: [
        IconButton(
          icon: Icon(Icons.check),
          onPressed: () => Navigator.pop(context),
        ),
      ],
    );
  }

  Widget _buildHeaderTabBar() {
    return SliverAppBar(
      automaticallyImplyLeading: false,
      expandedHeight: 224,
      floating: true,
      elevation: 0,
      flexibleSpace: FlexibleSpaceBar(
          background: Image.network("https://picsum.photos/250?image=9",
              fit: BoxFit.cover)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppbar(),
      body: DefaultTabController(
        length: 2,
        child: CustomScrollView(
          slivers: <Widget>[
            _buildHeaderTabBar(),
            SliverToBoxAdapter(
              child: TabBar(
                indicatorWeight: 2,
                tabs: [
                  Tab(text: 'Informations'),
                  Tab(text: 'Informations'),
                ],
              ),
            ),
            SliverFillRemaining(
              child: Column(
                children: [
                  Expanded(
                    child: TabBarView(
                      children: [
                        EditionInformationsTab(),
                        Center(child: Text("Tab 2")),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class EditionInformationsTab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _EditionInformationsTabState();
}

class _EditionInformationsTabState extends State<EditionInformationsTab> {
  final _list1 = <String>['Culture', 'Test'];
  final _list2 = <String>['Etablissement', 'Test 1', 'Test 2'];

  List<DropdownMenuItem<String>> _menuItemsGenerator(List<String> values) =>
      values
          .map<DropdownMenuItem<String>>((e) => DropdownMenuItem<String>(
                value: e,
                child: Text(e),
              ))
          .toList();

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Padding(
        padding: EdgeInsets.only(top: 16, left: 16, right: 16),
        child: Form(
          child: Column(
            children: [
              Padding(
                padding: EdgeInsets.only(bottom: 24),
                child: DropdownButtonFormField<String>(
                  value: _list1.first,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(4))),
                  items: _menuItemsGenerator(_list1),
                  onChanged: (_) {},
                ),
              ),
              Padding(
                padding: EdgeInsets.only(bottom: 24),
                child: DropdownButtonFormField(
                  value: _list2.first,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(4))),
                  items: _menuItemsGenerator(_list2),
                  onChanged: (_) {},
                ),
              ),
              TextFormField(
                maxLength: 30,
                decoration: InputDecoration(
                    labelText: "Nom de l'offre",
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(4))),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: DealsEditionPage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}