颤振堆栈布局容器使用剩余高度

时间:2020-07-01 17:10:50

标签: flutter flutter-layout

我从 Flutter 开始。

我正在建立一个外观看起来像

enter image description here

我正在使用 Stack 构建此布局,其中背景色的部分是另一个 Stack 子级,其父级 Container 高度为固定值。

我到目前为止编写的代码是

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:whatsappwithoutcontact/components/form_fields.dart';
import 'package:whatsappwithoutcontact/screens/info/info-screen.dart';


class MessageScreen extends StatefulWidget {
  @override
  _MessageScreenState createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WhatsApp without Contact'),
        backgroundColor: Colors.transparent,
        elevation: 0.0,
        actions: [
          IconButton(
            icon: Icon(Icons.info),
            onPressed: _onInfoPressed,
          )
        ],
      ),
      extendBodyBehindAppBar: true,
      body: MessageContainer()
    );
  }

  void _onInfoPressed() {
    Navigator.of(context).push(
      MaterialPageRoute<void> (
        builder: (BuildContext context) {
          return InfoScreen();
        }
      )
    );
  }
}

class MessageContainer extends StatefulWidget {
  @override
  _MessageContainerState createState() => _MessageContainerState();
}

class _MessageContainerState extends State<MessageContainer> {
  static const double avatarRadius = 35;
  static const double titleBottomMargin = (avatarRadius * 2) + 18;
  static const double _headerHeight = 350.0;
  final _formKey = GlobalKey<FormState>();
  final _messageFieldFocusNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Stack(
        children: [
          Container(
            height: _headerHeight,
            child: Stack(
              children: <Widget>[
                Container(
                  child: ClipPath(
                    clipper: HeaderClipper(avatarRadius: avatarRadius),
                    child: CustomPaint(
                      size: Size(MediaQuery.of(context).size.width, _headerHeight),
                      painter: HeaderPainter(
                          color: Colors.green,
                          avatarRadius: avatarRadius
                      ),
                    ),
                  ),
                ),
                Positioned(
                  left: 0,
                  right: 0,
                  child: Container(
                    padding: EdgeInsets.only(top: 80.0),
                    margin: EdgeInsets.all(50.0),
                    child: Column(
                      children: <Widget>[
                        FormTextField(
                          labelText: 'Country Code',
                          validator: (value) {
                            if (value.isEmpty) {
                              return 'Required';
                            }
                            return null;
                          }
                        ),
                        SizedBox(height: 15.0,),
                        FormTextField(
                          labelText: 'Phone Number',
                          validator: (value) {
                            if (value.isEmpty) {
                              return 'Required';
                            }
                            return null;
                          },
                        )
                      ],
                    ),
                  ),
                ),
                Align(
                  alignment: Alignment.bottomCenter,
                  child: CircleAvatar(
                    radius: avatarRadius,
                    backgroundColor: Colors.green,
                    child: IconButton(icon: Icon(Icons.message), onPressed: _onAddMessageButtonClick,),
                  ),
                )
              ],
            ),
          ),
          SingleChildScrollView(
            child: Padding(
              padding: EdgeInsets.symmetric(
                vertical: _headerHeight,
                horizontal: 50
              ),
              child: Column(
                children: [
                    TextFormField(
                      keyboardType: TextInputType.multiline,
                      maxLines: 4,
                      focusNode: _messageFieldFocusNode,
                      decoration: InputDecoration(
                        labelText: 'Message',
                        fillColor: Colors.white,
                        labelStyle: TextStyle(
                          color: _messageFieldFocusNode.hasFocus ? Colors.green : Colors.grey
                        ),
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.grey
                          )
                        ),
                        focusedBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.green
                          )
                        )
                      ),
                    )
                ],
              ),
            ),
          ),
        ],
      )
    );

  }
}

第一个堆栈中的第一个 Container 是绿色背景部分,而 SingleChildScrollView 是绿色背景以下的部分。

SingleChildScrollView 使下部滚动,而我希望将其固定并占据中心message图标下方的剩余空间。

我尝试使用容器,但是没有显示Message输入字段。

  1. 如何使用堆栈布局下方的剩余空间?
  2. 根据设计,我的布局结构是否良好?我需要改善的建议,如果不好的话。

1 个答案:

答案 0 :(得分:1)

将第一个Stack小部件替换为Column,现在您可以将SingleChildScrollView小部件包装到Expanded小部件中,Expanded小部件仅在{ {1}}和Column来填充可用空间。

不要忘记从Row输入字段中删除垂直padding