【问题标题】:flutter: ListTile how to adapt leading margins and title/subtitle style?flutter: ListTile 如何调整前导边距和标题/副标题样式?
【发布时间】:2018-10-05 07:59:43
【问题描述】:

我正在构建一个由各种小部件组成的表单,我想将它们全部对齐。

在以下示例中,我使用了 TextFormField、ListTile 等。

问题与 TextFormField > decoration > icon 和 ListTile >leading 的对齐有关。

如您所见,ListTile > 前导绝对不与 TextFormField > 装饰 > 图标对齐。

在文档中,我找不到任何关于如何调整 ListTile > 前导“margin left”的解释

子问题:如何设置 ListTile 标题和副标题的样式,使其看起来像 TextFormField?

我们非常欢迎任何帮助。

源码摘录:

_buildBody() {
    return new SafeArea(
      top: false,
      bottom: false,
      child: new Form(
        key: _formKey,
        autovalidate: false,
        child: new SingleChildScrollView(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              /* -- Profile Picture -- */
              const SizedBox(height: 24.0),
              _buildProfilePicture(),

              /* -- Alias -- */
              new TextFormField(
                decoration: const InputDecoration(
                  border: const UnderlineInputBorder(),
                  filled: true,
                  icon: const Icon(Icons.person),
                  hintText: 'Enter an alias',
                  labelText: 'Alias *',
                ),
                onSaved: (String value) {
                  profile.alias = value;
                },
                validator: _validateAlias,
              ),
              const SizedBox(height: 24.0),

              /* -- Gender -- */
              _buildGender(context),
              const SizedBox(height: 24.0),

              /* -- Self description -- */
              new TextFormField(
                decoration: const InputDecoration(
                  border: const OutlineInputBorder(),
                  hintText: 'Tell us about yourself',
                  labelText: 'Describe yourself',
                ),
                maxLines: 5,
              ),
              const SizedBox(height: 24.0),

              /* -- Save Button -- */
              new Center(
                child: new RaisedButton(
                  child: const Text('Save'),
                  onPressed: _handleSave,
                ),
              ),
              const SizedBox(height: 24.0),
            ],
          ),
        ),
      ),
    );
  }

_buildGender(BuildContext context) {
    return new GestureDetector(
      child: new ListTile(
        leading: new Container(width: 24.0, height: 24.0, color: Colors.red),//const Icon(Icons.casino),
        title: const Text('Gender'),
        subtitle: new Text(profile.gender),
        trailing: const Icon(Icons.arrow_drop_down),
        dense: true,
      ),
      onTap: () async {
        await showModalBottomSheet<void>(
          context: context,
          builder: (BuildContext context){
            return _buildGenderBottomPicker();
          },
        );
      }
    );
  }

快照: (我已经标记了错位)

【问题讨论】:

  • 您可以在传递给leading: ...(和title,subtitle,...)的小部件周围添加填充和边距
  • 这与问题无关,但根据材料设计风格指南,您不应使用相邻的两个 FAB 按钮。

标签: flutter


【解决方案1】:

由于我找不到任何适合 ListTile 的直接解决方案,并且无法通过负边距来更正 ListTile 设置的默认设置(请参阅其源代码),因此我决定构建自己的解决方案(简化版):

这是我提供的解决方案:

_buildGender(BuildContext context) {
    List<Widget> children = <Widget>[];
/* -- leading -- */
children.add(new Container(
  width: 40.0,
  alignment: AlignmentDirectional.centerStart,
  child: const Icon(Icons.album, color: Colors.grey),
));

/* -- title & subtitle -- */
children.add(new Expanded(
  child: new Container(
    height: 48.0,
    padding: const EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0),
    decoration: new BoxDecoration(
      color: Color.fromRGBO(0, 0, 0, 0.05),
      border: new Border(bottom: new BorderSide(color: Colors.black)),
    ),
    child: new Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        new Text('Gender',
            style: new TextStyle(color: Colors.blue, fontSize: 12.0)),
        const SizedBox(height: 5.0),
        new Text(profile.gender),
      ],
    ),
  ),
));

/* -- trailing -- **/
children.add(new Container(
  width: 40.0,
  height: 48.0,
  alignment: AlignmentDirectional.centerEnd,
  decoration: new BoxDecoration(
      color: Color.fromRGBO(0, 0, 0, 0.05),
      border: new Border(bottom: new BorderSide(color: Colors.black)),
    ),
  child: const Icon(Icons.arrow_drop_down),
));

return new InkWell(
    child: new Semantics(
      child: new ConstrainedBox(
        constraints: new BoxConstraints(minHeight: 60.0),
        child: new UnconstrainedBox(
          constrainedAxis: Axis.horizontal,
          child: new SafeArea(
            top: false,
            bottom: false,
            child: new Row(children: children),
          ),
        ),
      ),
    ),
    onTap: () async {
      await showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return _buildGenderBottomPicker();
        },
      );
    });

}

和我得到的布局:

当然还有一些工作要做来改进代码、使用主题并最终使其成为一个小部件,但这只是开始。

我只是想和你分享这段代码。

【讨论】:

    【解决方案2】:

    修饰预定义的领先差距

    Ctrl 点击ListTile Widget > 搜索_minLeadingWidth (ctrl +f ) > 默认40,改成10什么的

    list_tile.dart screenshot

    【讨论】:

      【解决方案3】:

      简单地将图标包装在高度为:double.infinity 的容器中

      ListTile(
                  leading: Container(
                      child:
                          Icon(Icons.account_circle),
                      height: double.infinity,)
      

      【讨论】:

      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-16
      相关资源
      最近更新 更多