【问题标题】:Flutter stack layout container use remaining heightFlutter 堆栈布局容器使用剩余高度
【发布时间】:2020-10-22 04:57:44
【问题描述】:

我从 Flutter 开始。

我正在构建一个看起来像这样的布局

我正在使用 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
                          )
                        )
                      ),
                    )
                ],
              ),
            ),
          ),
        ],
      )
    );

  }
}

第一个Stack中的第一个Container是绿色背景部分,SingleChildScrollView是绿色背景下面的部分。

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

我尝试使用 Container,但未显示 Message 输入字段。

  1. 如何使用 Stack 布局下方的剩余空间?
  2. 我的布局结构是否符合设计。我需要关于如何改进它的建议,如果不好的话。

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    将第一个Stack 小部件替换为Column,现在您可以将SingleChildScrollView 小部件包装到Expanded 小部件中,Expanded 小部件仅在ColumnRow 内工作以填充可用的空间。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2018-04-09
      • 2014-08-21
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 2021-06-08
      相关资源
      最近更新 更多