【问题标题】:How can I create Expanded panel如何创建扩展面板
【发布时间】:2018-04-10 18:02:38
【问题描述】:

HereExpanded panel 的材料设计,看起来像:

我想用Flutter做一个类似的,不知道我是否必须从下面的代码开始或知道如何完成它!

new ExpansionPanelList(
  children: <ExpansionPanel>[
    new ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
            isExpanded = true;
            return new ListTile(
            // leading: item.iconpic,
            title: new Text(
            "First",
            textAlign: TextAlign.left,
            style: new TextStyle(
            fontSize: 20.0,
            fontWeight: FontWeight.w400,
            ),
            ));
          },
      body: new Text("school"),
      isExpanded: true,
    ),
    new ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        isExpanded = true;
        return new ListTile(
          // leading: item.iconpic,
            title: new Text(
              "Second",
              textAlign: TextAlign.left,
              style: new TextStyle(
                fontSize: 20.0,
                fontWeight: FontWeight.w400,
              ),
            ));
      },
      isExpanded: false,
      body: new Text("hospital"),
    ),
    new ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          isExpanded = true;
          return new ListTile(
            // leading: item.iconpic,
              title: new Text(
                "Third",
                textAlign: TextAlign.left,
                style: new TextStyle(
                  fontSize: 20.0,
                  fontWeight: FontWeight.w400,
                ),
              ));
        },
        body: new Text("va facility"),
        isExpanded: true)
    ]),

更新

我只需要开始并拥有空面板

【问题讨论】:

  • 您不太清楚您要在这里做什么。你想复制整个东西,从上到下(包括巴巴多斯标签等)?您在构建扩展面板时遇到问题吗?你在布局上有问题吗?发布一张您拥有的照片并告诉我们您拥有的和您想看到的之间的区别会很有用。
  • @rmtmckenzie 我无法构建扩展面板,不知道如何开始
  • @aziza 我读过那个,但不明白或不知道如何开始,请查看我对问题的更新。
  • 您希望图像中的外观完全相同(单独卡片中的标题部分和正文部分)?

标签: dart flutter


【解决方案1】:

如果您特别需要模仿您从材料设计中引用的图像。您会想要构建自己的自定义扩展面板。

我有一个使用AnimatedContainer 的简单示例,向您展示如何创建展开和折叠效果,您可以根据需要填充标题和正文部分。

class AnimateExpanded extends StatefulWidget {
  @override
  _AnimateExpandedState createState() => new _AnimateExpandedState();
}

class _AnimateExpandedState extends State<AnimateExpanded> {
  double _bodyHeight = 0.0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: Colors.grey[500],
      body: new SingleChildScrollView(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Card(
              child: new Container(
                height: 50.0,
                child: new Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    new IconButton(
                      icon: new Icon(Icons.keyboard_arrow_down),
                      onPressed: () {
                        setState(() {
                          this._bodyHeight = 300.0;
                        });
                      },
                    )
                  ],
                ),
              ),
            ),
            new Card(
              child: new AnimatedContainer(
                child: new Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    new IconButton(
                      icon: new Icon(Icons.keyboard_arrow_up),
                      onPressed: () {
                        setState(() {
                          this._bodyHeight = 0.0;
                        });
                      },
                    ),
                  ],
                ),
                curve: Curves.easeInOut,
                duration: const Duration(milliseconds: 500),
                height: _bodyHeight,
                // color: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【讨论】:

  • 什么图片,你的意思是答案中的gif?
  • 我使用 ScreenToGif
  • 嗨,我对 Flutter 有点陌生。我只想问我是否在同一个屏幕上有多个可折叠。我该如何处理。我目前正在使用您的代码@aziza,它对 1 工作正常,但是当我添加多个时,如果我点击其中任何一个,它会打开所有可折叠项
  • 这太棒了!您如何使“打开”高度动态化,特别是等于 AnimatedContainer 的孩子的总高度(在我的例子中是一个具有多个孩子的列)?
【解决方案2】:

这是一个工作示例(包括 main 等,因此您可以粘贴到文件中并运行)

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class ListItem {
  final WidgetBuilder bodyBuilder;
  final String title;
  final String subtitle;
  bool isExpandedInitially;

  ListItem({
    @required this.bodyBuilder,
    @required this.title,
    this.subtitle = "",
    this.isExpandedInitially = false,
  })  : assert(title != null),
        assert(bodyBuilder != null);

  ExpansionPanelHeaderBuilder get headerBuilder =>
      (context, isExpanded) => new Row(children: [
            new SizedBox(width: 100.0, child: new Text(title)),
            new Text(subtitle)
          ]);
}

class ExpansionList extends StatefulWidget {
  /// The items that the expansion list should display; this can change
  /// over the course of the object but probably shouldn't as it won't
  /// transition nicely or anything like that.
  final List<ListItem> items;

  ExpansionList(this.items) {
    // quick check to make sure there's no duplicate titles.
    assert(new Set.from(items.map((li) => li.title)).length == items.length);
  }

  @override
  State<StatefulWidget> createState() => new ExpansionListState();
}

class ExpansionListState extends State<ExpansionList> {
  Map<String, bool> expandedByTitle = new Map();

  @override
  Widget build(BuildContext context) {
    return new ExpansionPanelList(
      children: widget.items
          .map(
            (item) => new ExpansionPanel(
                headerBuilder: item.headerBuilder,
                body: new Builder(builder: item.bodyBuilder),
                isExpanded:
                    expandedByTitle[item.title] ?? item.isExpandedInitially),
          )
          .toList(growable: false),
      expansionCallback: (int index, bool isExpanded) {
        setState(() {
          expandedByTitle[widget.items[index].title] = !isExpanded;
        });
      },
    );
  }
}

void main() => runApp(
      new MaterialApp(
        home: new SingleChildScrollView(
          child: new SafeArea(
            child: new Material(
              child: new ExpansionList(
                [
                  new ListItem(
                      title: "Title 1",
                      subtitle: "Subtitle 1",
                      bodyBuilder: (context) => new Text("Body 1")),
                  new ListItem(
                      title: "Title 2",
                      subtitle: "Subtitle 2",
                      bodyBuilder: (context) => new Text("Body 1"),
                      isExpandedInitially: true)
                ],
              ),
            ),
          ),
        ),
      ),
    );

如果我不得不猜测,您会错过将扩展传递到每个扩展标头的部分,以及您跟踪每个扩展标头是否已扩展的部分。

我在这里采用了一种特殊的方式,假设每个标题都是唯一的;您可以做类似的事情,但依赖于不同的属性。或者,您可以在您的 ExpansionListState 等效项的 initState 方法中构建所有内容。

This 是一个完整的工作示例,几乎与您帖子中图片中的用户界面完全相同。您只需从 Play 商店下载flutter gallery 即可查看结果。他们的做法与我不同(在 initState 方法中构建所有内容),而且比我所做的更复杂,但也值得理解。

希望对您有所帮助 =)

【讨论】:

    【解决方案3】:

    您可以像这样在ListView 中使用ExpansionTile

            ListView(
                  shrinkWrap: true,
                  children: <Widget>[
                    ExpansionTile(
                      backgroundColor: Colors.amber,
                      leading: Icon(Icons.event),
                      title: Text('Test1'),
                      children: <Widget>[
                        ListTile(title: Text('Title of the item')),
                        ListTile(
                          title: Text('Title of the item2'),
                        )
                      ],
                    ),
                    ExpansionTile(
                      title: Text('Test2'),
                      children: <Widget>[
                        ListTile(title: Text('Title of the item')),
                        ListTile(
                          title: Text('Title of the item2'),
                        )
                      ],
                    )
                  ],
                )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多