简体   繁体   English

在 Column 内居中扩展 ListView Flutter

[英]Center Expanded ListView inside Column Flutter

I'm trying to build a layout where there are two Text objects at the top and bottom which stays stationery and a ListView at their center.我正在尝试构建一个布局,其中顶部和底部有两个 Text 对象,它们保持文具状态,而 ListView 位于它们的中心。

Here's the code for the Screen这是屏幕的代码

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 40.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Container(
                margin: EdgeInsets.symmetric(vertical: 40.0),
                child: Text(
                  DateFormat("hh:mm 'PM ,'  MMMM d").format(DateTime.now()),
                  style: Theme.of(context).textTheme.title,
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: 4,
                  itemBuilder: (BuildContext context, int index) =>
                      CustomAppText(
                        text: 'Custom App',
                      ),
                ),
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 40.0),
                child: Text(
                  "Settings",
                  style: Theme.of(context).textTheme.title,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

The output of the given code给定代码的output 给定代码的输出

The Design I'm looking for我正在寻找的设计期望的输出

I have tried using the Center widget but it does not center the ListView我试过使用 Center 小部件,但它没有使 ListView 居中

The ListView fills the entire Expanded Widget, that's why using the Center widget didn't work, so shrinkWrap: true should be added so the ListView takes only the height of it's children. ListView 填充了整个 Expanded Widget,这就是为什么使用 Center 小部件不起作用的原因,因此应该添加shrinkWrap: true以便 ListView 仅采用其子项的高度。

After skimming through the documentation I found about Flexible Widget浏览文档后,我发现了有关灵活小部件的信息

Flexible, which does not force the child to fill the available space.

Made the change and works like a charm做出改变,就像一个魅力

Flexible(
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: 4,
                  itemBuilder: (BuildContext context, int index) =>
                      CustomAppText(
                        text: 'Custom App',
                      ),
                ),
              ),

For those still looking for an answer, this is what worked for me:对于那些仍在寻找答案的人,这对我有用:

Column(
  children: [

    Container(), // some top content

    Expanded(
      child: Center(
        child: ListView(
          shrinkWrap: true,
          children: [] //your list view content here
        )
      )
    ),

    Container(), // some bottom content

  ]
)

The Expanded widget makes the content take up all available space. Expanded小部件使内容占据所有可用空间。

The Center widget centers the content you want to display.中心小部件将您要显示的内容居中。

The ListView holds your list content and the "shrinkWrap: true" property makes your list view shrink according to content size(allowing it to centralized by the Center widget when it's not taking a lot of space). ListView保存您的列表内容,而"shrinkWrap: true"属性使您的列表视图根据内容大小缩小(允许它在不占用大量空间时由Center小部件集中)。

Hope it helps.希望能帮助到你。 Give the top and bottom widgets the 25% of the screen size.为顶部和底部小部件提供屏幕尺寸的 25%。 Give the listview the 50% of the screen size.为列表视图提供屏幕尺寸的 50%。

import 'package:flutter/material.dart';

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    final _size = MediaQuery.of(context).size;

    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(28.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              // Top Widgets
              Container(
                width: double.infinity,
                // color: Colors.green,
                height: _size.height * 0.25, // Take 25% width of the screen height
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text('11: 25 AM', style: TextStyle(fontSize: 23.0),),
                    Text('Set As Launcher', style: TextStyle(fontSize: 23.0),)
                  ],
                ),
              ),

              Expanded(
                child: Container(
                  // color: Colors.yellow,
                  child: ListView(
                    children: List.generate(25, (index){
                      return Text('Custom App $index', style: TextStyle(fontSize: 45.0),);
                    }),
                  ),
                ),
              ),

              // Bottom Widgets
              Container(
                width: double.infinity,
                // color: Colors.blue,
                height: _size.height * 0.25, // Take 25% width of the screen height
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text('Settings', style: TextStyle(fontSize: 23.0),),                    
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

在此处输入图片说明

Just add an Expanded as a wrapper for your first Container inside the Column只需为Column内的Column一个Container添加一个Expanded作为包装器

        Expanded(
                        child: Container(
                          margin: EdgeInsets.symmetric(vertical: 40.0),
                          child: Text(
                            DateFormat("hh:mm 'PM ,'  MMMM d").format(DateTime.now()),
                            style: Theme.of(context).textTheme.title,
                          ),
                        ),
                      ),

Just wrap your ListView.builder inside a container class and give it a height, either explicitly in double or as a percentage of screen height.只需将您的 ListView.builder 包装在一个容器类中并给它一个高度,明确地以双倍或屏幕高度的百分比表示。

class Trial extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 40.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Container(
                margin: EdgeInsets.symmetric(vertical: 40.0),
                child: Text(
                  "Some Text",
                  style: Theme.of(context).textTheme.title,
                ),
              ),
              Container(
//                height: 40,
                height: MediaQuery.of(context).size.height * 0.4,
                child: ListView.builder(
                  itemCount: 20,
                  itemBuilder: (BuildContext context, int index) {
                    return Text("Hello");
                  }
                ),
              ),
              Container(
                margin: EdgeInsets.symmetric(vertical: 40.0),
                child: Text(
                  "Settings",
                  style: Theme.of(context).textTheme.title,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Add two spacer it will give you 100% same result as you expected添加两个垫片,它会给你 100% 与你预期相同的结果

      Spacer(),
          Expanded(
            child: ListView.builder(
              itemCount: 4,
              itemBuilder: (BuildContext context, int index) =>
                  CustomAppText(
                    text: 'Custom App',
                  ),
            ),
          ),
          Spacer(),

It have to use shrinkWrap: true and Flexible together to show all items of ListView.它必须同时使用 shrinkWrap: true 和 Flexible 才能显示 ListView 的所有项目。

Flexible(
        child: ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: Axis.vertical,
          itemCount: models.length,

如果你用Container替换你的Expanded小部件并给它一个固定的height ,我想你会得到你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM