【问题标题】:Align ListView's children to top and bottom将 ListView 的子项对齐到顶部和底部
【发布时间】:2019-03-02 09:24:09
【问题描述】:

TL;DR

是否可以像Column's spaceBetween 对齐ListView's 子级对齐?

就像这个截图:

我试图解决的问题:

一开始我有一个带有 2 个孩子的 Column 小部件。 Column's 对齐设置为 spaceBetween。这就是我想要的,顶部一个小部件,底部一个。但是当我单击输入以添加凭据时,键盘导致此 GitHub issue 中描述的溢出问题。所以为了修复它,我用ListView 替换了Column。但现在我的孩子小部件卡在屏幕顶部。

我的完整LoginScreen代码:

import 'package:flutter/material.dart';

import '../widgets/button.dart';
import '../widgets/input.dart';
import '../widgets/logo.dart';

class LoginScreen2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Background(),
          Wrapper(),
        ],
      ),
    );
  }
}

class Background extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          colors: [
            Color(0xfff6f6f6),
            Colors.white,
          ],
        ),
      ),
    );
  }
}

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Logo(LogoColor.dummy_black),
        Align(
          alignment: Alignment.bottomCenter,
          child: Padding(
            padding: const EdgeInsets.all(20),
            child: BottomPart(),
          ),
        ),
      ],
    );
  }
}

class BottomPart extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Input('User name'),
        Input('Password'),
        Button(
          'Log in',
          onPressed,
        ),
      ],
    );
  }

  void onPressed() {}
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    你可以使用 ListView 的属性 reverse

    reverse: true,
    

    然后更改 ListView 子项的顺序。

    【讨论】:

    • 哇,很酷的解决方案
    【解决方案2】:

    找到解决方案。您应该用 minHeight 将您的 Column 包装在 IntrinsicHeight 和 ConstrainedBox 中。

    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return SingleChildScrollView(
          child: IntrinsicHeight(
            child: ConstrainedBox(
              constraints: BoxConstraints(
                minHeight: MediaQuery.of(context).size.height,
              ),
              child: Column(
                children: [
                  Container(
                    height: 100,
                    width: double.infinity,
                    color: Colors.yellow,
                    child: Text('1', style: TextStyle(color: Colors.black)),
                  ),
                  Spacer(),
                  Container(
                    height: 100,
                    width: double.infinity,
                    color: Colors.red,
                    child: Text('2', style: TextStyle(color: Colors.black)),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      我终于找到了解决这个问题的方法。使用代码:`

      Align(
          alignment: Alignment.bottomCenter,
          child: ListView(
            shrinkWrap: true,
            children: <Widget>[
              // Your Widget Here
            ],
          ),
        ),
      

      【讨论】:

        【解决方案4】:

        尝试在 b/w Logo 小部件和 Align(底部)中使用 SizedBox(height:50.0) // or any other value

         return ListView(
              children: <Widget>[
                Logo(LogoColor.dummy_black),
                SizedBox(height: MediaQuery.of(context).size.height/ 3),// you will get value which is 1/3rd part of height of your device screen
                Align(
                  alignment: Alignment.bottomCenter,
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: BottomPart(),
                  ),
                ),
              ],
            );
        

        【讨论】:

        • 那么空间将固定高度。因此,如果我在平板电脑上打开我的应用,底部将位于平板电脑屏幕的中心。
        • 嗯,使用媒体查询获取 height/3 值并使用 sizedBox 高度或使用媒体查询将脚手架分成两部分(容器),这将根据其高度划分屏幕。在顶部添加徽标,在底部添加登录表单。
        • 更简单的方法是将其包装在 Container 中,并使用屏幕大小高度,然后添加具有 spaceBetween 属性的 Column。谢谢你的想法。
        【解决方案5】:

        你可以在 logo 和 Align 之间插入这个

            Expanded(child: SizedBox(height: 8)),
        

        【讨论】:

          【解决方案6】:

          您可以从 ListView 中取出底部部分,并将其放在 Stack 的最后一个子项中。您的 Wrapper 可能如下所示:

          Widget build(BuildContext context){
              var bottomHeight = 120.0;//replaced with your BottomPart's height
              return Stack(
                children: [
                  ListView(),//your ListView
                  Positioned(
                      top: MediaQuery.of(context).size.height - bottomHeight,
                      child: SizedBox(
                        height: bottomHeight,
                        child: BottomPart(),
                      )
                  )
                ],
              );
            }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-19
            • 2015-09-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多