【问题标题】:Everything expands to screenwidth inside a Listview. Can I change that?一切都扩展到 Listview 内的屏幕宽度。我可以改变它吗?
【发布时间】:2018-04-13 15:14:10
【问题描述】:

我正在尝试为我正在制作的应用设计聊天屏幕。 为了使其可滚动,我将所有聊天消息都放在了一个列表视图中。但是我放置在列表视图中的所有内容都会水平扩展以匹配屏幕宽度(Listview 小部件具有的宽度)。我可以将其关闭,以便我可以将我的聊天消息排到一侧,而将另一侧的聊天消息排到另一侧,就像在 whatsapp 中一样?只要我可以滚动,除了 ListView 解决方案之外的任何东西都可以

这就是现在的样子。

这是我当前页面的代码。我真的希望有人可以帮助我解决这个问题。

import 'package:flutter/material.dart';
//import '../../Library/Library.dart';
//import '../../Ui/ChatMessage.dart';

class ChatScreen extends StatefulWidget {
    @override
    State<StatefulWidget> createState() {
        return new ChatScreenState();
    }
}

class ChatScreenState extends State<ChatScreen> {

    bool overlayShouldBeVisible = false;

    @override
    Widget build(BuildContext context) {
        return new Stack(
            fit: StackFit.expand,
            children: <Widget>[
                new Scaffold(
                    appBar: new AppBar(
                        title: new Text(
                            'Chatroom name',
                            style: new TextStyle(
                                color: Colors.black,
                            ),
                        ),
                        centerTitle: true,
                        backgroundColor: Colors.white,
                        elevation: 0.0,
                    ),
                    body: new Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                            new Expanded(
                                child: new Container(
                                    decoration: new BoxDecoration(
                                        //image: new DecorationImage(image: new AssetImage('assets/backgroundChat.jpg',),fit: BoxFit.cover)
                                    ),
                                    child: new ListView(
                                        children: <Widget>[
                                            new Text('Test'),
                                            new Card(
                                                color: Colors.green,
                                                child: new Padding(
                                                    padding: new EdgeInsets.all(7.0),
                                                    child: new Column(
                                                        crossAxisAlignment: CrossAxisAlignment.end,
                                                        children: <Widget>[
                                                            new Text('Message'),
                                                            new Text('17:00'),
                                                        ],
                                                    ),
                                                ),
                                            ),
                                            new Card(
                                                color: Colors.green,
                                                child: new Padding(
                                                    padding: new EdgeInsets.all(7.0),
                                                    child: new Column(
                                                        crossAxisAlignment: CrossAxisAlignment.end,
                                                        children: <Widget>[
                                                            new Text('Message'),
                                                            new Text('17:00'),
                                                        ],
                                                    ),
                                                ),
                                            ),
                                        ],
                                    ),
                                ),
                            ),
                            new Container(
                                height: 50.0,
                                color: Colors.white,
                                child: new Row(
                                    crossAxisAlignment: CrossAxisAlignment.stretch,
                                    children: <Widget>[
                                        new Expanded(
                                            child: new Padding(
                                                padding: new EdgeInsets.only(left: 20.0),
                                                child: new TextField(),
                                            ),
                                        ),
                                        new Material(
                                            color: Colors.white,
                                            child: new InkWell(
                                                child: new Padding(
                                                    padding: new EdgeInsets.symmetric(horizontal: 20.0),
                                                    child: new Icon(
                                                        Icons.send,
                                                        color: Colors.blue,
                                                    ),
                                                ),
                                                onTap: () => print('send'),
                                            ),
                                        ),
                                    ],
                                ),
                            ),
                        ],
                    ),
                ),
                //overlayShouldBeVisible == true ? new JsonLoader(): new Container(),
                //Library.debugMode ? new DebugOverlay(): new Container(),
            ],
        );
    }
}

【问题讨论】:

  • 是的,我希望 Listview 占用所有可用(垂直)空间。除了使用扩展之外,还有其他方法吗?
  • 什么意思?
  • 好的!谢谢你:)

标签: flutter


【解决方案1】:

您可以使用Align 小部件将其子元素与父元素对齐。

只需将列表节点(卡片实例)包装在 Align 中。

 import 'package:flutter/material.dart';
//import '../../Library/Library.dart';
//import '../../Ui/ChatMessage.dart';

void main() {
  runApp(
    new MaterialApp(
      home: new ChatScreen(),
    ),
  );
}

class ChatScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new ChatScreenState();
  }
}

class ChatScreenState extends State<ChatScreen> {
  bool overlayShouldBeVisible = false;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(body: new ListView.builder(
      itemBuilder: (context, index) {
        return new Align(
          alignment: index.isEven ? Alignment.centerLeft : Alignment.centerRight,
          child: new Card(
            child: new Padding(
              padding: const EdgeInsets.all(8.0),
              child: new Text("Hello World $index"),
            ),
          ),
        );
      },
    ));
  }
}

【讨论】:

  • 也是一个非常好的解决方案!看起来这一切都归结为将卡片放在 Align 或 Row 内以阻止其宽度为 100%!谢谢!
  • 行是个坏主意。 Align 用于单子对齐。行是为多个孩子:)
  • 你只需要用 Wrap() 小部件包裹你不希望占据整个屏幕宽度的子小部件。
【解决方案2】:

我对您的代码做了一些重构,结果如下:

基本上我会为消息类型(发送或接收)保留一个标志,并相应地对齐消息卡

请注意,我没有时间查看代码,但我注意到有很多不必要的嵌套,因此您可能需要稍微修改一下布局

class ChatScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new ChatScreenState();
  }
}

class ChatMessage extends StatelessWidget {
  String type;
  ChatMessage({this.type});
  @override
  Widget build(BuildContext context) {
    return new Row(
      mainAxisAlignment:
          this.type == "sent" ? MainAxisAlignment.end : MainAxisAlignment.start,
      children: <Widget>[
        new Card(
          color: Colors.green,
          child: new Padding(
            padding: new EdgeInsets.all(7.0),
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: <Widget>[
                new Text('Message'),
                new Text('17:00'),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

class ChatScreenState extends State<ChatScreen> {
  bool overlayShouldBeVisible = false;

  @override
  Widget build(BuildContext context) {
    return new Stack(
      fit: StackFit.expand,
      children: <Widget>[
        new Scaffold(
          appBar: new AppBar(
            title: new Text(
              'Chatroom name',
              style: new TextStyle(
                color: Colors.black,
              ),
            ),
            centerTitle: true,
            backgroundColor: Colors.white,
            elevation: 0.0,
          ),
          body: new Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              new Expanded(
                child: new Container(
                  decoration: new BoxDecoration(
                      //image: new DecorationImage(image: new AssetImage('assets/backgroundChat.jpg',),fit: BoxFit.cover)
                      ),
                  child: new ListView(
                    children: <Widget>[
                      new ChatMessage(
                        type: "sent",
                      ),
                      new ChatMessage(
                        type: "sent",
                      ),
                      new ChatMessage(
                        type: "received",
                      ),
                      new ChatMessage(
                        type: "sent",
                      ),
                      new ChatMessage(
                        type: "received",
                      ),
                      new ChatMessage(
                        type: "received",
                      ),
                    ],
                  ),
                ),
              ),
              new Container(
                height: 50.0,
                color: Colors.white,
                child: new Row(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    new Expanded(
                      child: new Padding(
                        padding: new EdgeInsets.only(left: 20.0),
                        child: new TextField(),
                      ),
                    ),
                    new Material(
                      color: Colors.white,
                      child: new InkWell(
                        child: new Padding(
                          padding: new EdgeInsets.symmetric(horizontal: 20.0),
                          child: new Icon(
                            Icons.send,
                            color: Colors.blue,
                          ),
                        ),
                        onTap: () => print('send'),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
        //overlayShouldBeVisible == true ? new JsonLoader(): new Container(),
        //Library.debugMode ? new DebugOverlay(): new Container(),
      ],
    );
  }
}

或者正如 Rémi 建议的那样,您可以像这样使用 Align 而不是 Row

return new Align(
      alignment:this.type!="sent"?  FractionalOffset.centerLeft:FractionalOffset.centerRight,
                  child: 
                    new Card(
    ..

【讨论】:

  • 哇,非常感谢。让我现在就去看看!
  • Align 是一个更直接的解决方案
  • 看代码结构没有太大变化。它的哪一部分使消息不占用整个屏幕宽度?只是为了我的知识,所以我知道将来如何工作。但效果惊人。非常感谢!
  • 哦,我想我明白了。是因为你把卡片排成一排吗?
  • @KevinWalter 是因为 Row 是的,你可能真的想查看@Rémi 评论,老实说,我没有想到 Align 但是的,这似乎是一个更好的解决方案。
【解决方案3】:

感谢您的回答。这个对我帮助更大:

flutter ListView children size

我最终得到了这样的代码:

  var sizeW = MediaQuery.of(context).size.width;
  var leftCut = 0.0;
  var rightCut = 0.0;
  if (sizeW > WEB_MAX_WIDTH) {
    leftCut = (sizeW - WEB_MAX_WIDTH) / 2;
    rightCut = leftCut;
  }

然后像这样使用:

          return Container(
            margin: EdgeInsets.only(right:rightCut, left: leftCut),
              padding:
                  EdgeInsets.only(left: (_fullList[index].level * 30.0)),
              child: Card(
                  child: ListTile(
                ...

【讨论】:

    【解决方案4】:

    我知道这有点晚了,但这可能是最简单的解决方案。我不知道这是否是一个好习惯(如果不是,您可以在下面评论)。

    我所做的是将消息(我的意思是包含消息的小部件)包装成一行,并根据消息是在右侧还是在左侧,首先或最后添加一个 Spacer() 小部件

    所以代码可能看起来像(下面的代码是左侧的消息)

    Row(
    children: [
      Card(
        color: Colors.green,
        child: new Padding(
          padding: new EdgeInsets.all(7.0),
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: <Widget>[
              new Text('Message'),
              new Text('17:00'),
            ],
          ),
        ), 
      )
      Spacer(),
    ]
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多