如何在 Flutter 中折叠其他 ExpansionTile 元素

Posted

技术标签:

【中文标题】如何在 Flutter 中折叠其他 ExpansionTile 元素【英文标题】:How to collapse other ExpansionTile elements in Flutter 【发布时间】:2020-02-12 09:26:49 【问题描述】:

我们有 3 个 ExpansionTiles 部分,在展开其中一个部分时,其他部分应该会折叠。很简单……但是:

在颤振文档中找不到任何有用的东西。 有谁知道如何做到这一点?

这是来自 Flutter 文档页面的示例代码。如果您单击第 A 章,B 和 C 应该折叠(如果可见),并且如果您然后单击 B 章,A 和 C 应该折叠......等等。

示例代码:

  // Copyright 2017 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.

  import 'package:flutter/material.dart';

  class ExpansionTileSample extends StatelessWidget 
    @override
    Widget build(BuildContext context) 
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('ExpansionTile'),
          ),
          body: ListView.builder(
            itemBuilder: (BuildContext context, int index) =>
                EntryItem(data[index]),
            itemCount: data.length,
          ),
        ),
      );
    
  

  // One entry in the multilevel list displayed by this app.
  class Entry 
    Entry(this.title, [this.children = const <Entry>[]]);

    final String title;
    final List<Entry> children;
  

  // The entire multilevel list displayed by this app.
  final List<Entry> data = <Entry>[
    Entry(
      'Chapter A',
      <Entry>[
        Entry('Section A1'),
        Entry('Section A2'),
      ],
    ),
    Entry(
      'Chapter B',
      <Entry>[
        Entry('Section B0'),
        Entry('Section B1'),
      ],
    ),
    Entry(
      'Chapter C',
      <Entry>[
        Entry('Section C0'),
        Entry('Section C1'),
      ],
    ),
  ];

  // Displays one Entry. If the entry has children then it's displayed
  // with an ExpansionTile.
  class EntryItem extends StatelessWidget 
    const EntryItem(this.entry);

    final Entry entry;

    Widget _buildTiles(Entry root) 
      if (root.children.isEmpty) return ListTile(title: Text(root.title));
      return ExpansionTile(
        key: PageStorageKey<Entry>(root),
        title: Text(root.title),
        children: root.children.map(_buildTiles).toList(),
      );
    

    @override
    Widget build(BuildContext context) 
      return _buildTiles(entry);
    
  

  void main() 
    runApp(ExpansionTileSample());
  

来源:Flutter: ExpansionTile sample

【问题讨论】:

请检查这个***.com/questions/48930372/… 【参考方案1】:

你可以考虑this answer in GitHub。

检查此示例:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'ExpansionTile Collapse',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'ExpansionTile Collapse'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  // selected's value = 0. For default first item is open.
  int selected = 0; //attention

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('ExpansionTile Collapse',
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
      ),
      body: Container(
        color: Colors.white,
        child: SingleChildScrollView(
          child: Column(children: [
            ListView.builder(
              key: Key('builder $selected.toString()'), //attention
              padding: EdgeInsets.only(left: 13.0, right: 13.0, bottom: 25.0),
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              itemCount: 5,
              itemBuilder: (context, index) 
                return Column(children: <Widget>[
                  Divider(
                    height: 17.0,
                    color: Colors.white,
                  ),
                  ExpansionTile(
                    key: Key(index.toString()), //attention
                    initiallyExpanded: index == selected, //attention

                    leading: Icon(
                      Icons.person,
                      size: 50.0,
                      color: Colors.black,
                    ),
                    title: Text('ExpansionTile $index',
                        style: TextStyle(
                            color: Color(0xFF09216B),
                            fontSize: 17.0,
                            fontWeight: FontWeight.bold)),
                    subtitle: Text(
                      'Software Engineer',
                      style: TextStyle(
                          color: Colors.black,
                          fontSize: 13.0,
                          fontWeight: FontWeight.bold),
                    ),
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.all(25.0),
                        child: Text(
                          'DETAİL $index \n' + 'Expanded',
                        ),
                      )
                    ],
                    onExpansionChanged: ((newState) 
                      if (newState)
                        setState(() 
                          Duration(seconds: 20000);
                          selected = index;
                        );
                      else
                        setState(() 
                          selected = -1;
                        );
                    ),
                  ),
                ]);
              ,
            )
          ]),
        ),
      ),
    );
  

实际输出:

【讨论】:

以上是关于如何在 Flutter 中折叠其他 ExpansionTile 元素的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 应用程序创建一个扩展面板列表

Flutter开发:折叠效果对应的组件使用

Flutter折叠展开列表的使用

Flutter折叠展开列表的使用

Flutter折叠展开列表的使用

如何通过某些变量折叠数据框,在其他变量中取平均值