1

开发环境

win10
Android Studio

clipboard.png

效果

用于多级菜单展示,或选择。
如 每个省,市,县;
如 树木的病虫害;

clipboard.png

clipboard.png

关键代码

  @override
  Widget build(BuildContext context) {
    return ListTile(

      title: _buildItem(widget.bean),
    );
  }

  Widget _buildItem(NameBean bean){
    if(bean.children.isEmpty){
      return ListTile(
        title: Text(bean.name),
        onTap: (){
          _showSeletedName(bean.name);
        },
      );
    }
    return ExpansionTile(
      key: PageStorageKey<NameBean>(bean),
      title: Text(bean.name),
      children: bean.children.map<Widget>(_buildItem).toList(),
      leading: CircleAvatar(
        backgroundColor: Colors.green,
        child: Text(bean.name.substring(0,1),style: TextStyle(color: Colors.white),),
      ),
    );
  }

分析

  • api:ExpansionTile
  • 算法:递归

1. ExpansionTile的使用

一般传入三个参数
key,title,children;

title:每一行上面的文字;
children:菜单下面的子条目,是一个数组;
key:根据源码传入PageStorageKey,用于保存滑动过程中的状态;

2. 递归

有的条目有子条目,有的没有,通过递归的方式遍历出每条数据;

通过 bean.children.isEmpty 来结束递归;
如 “直辖市”中的北京,下面没有 “市”了,也就是children.isEmpty,此时应该结束递归,返回 ListTile;
如“省级行政单位” 下面的 “黑龙江”还有很多个“市”,还不需要继续遍历返回 层级菜单ExpansionTile;

3. 源码

学习flutter,很多不了解的地方都可以试着看看对应源码上面的注释。

/// A single-line [ListTile] with a trailing button that expands or collapses
/// the tile to reveal or hide the [children].
///
/// This widget is typically used with [ListView] to create an
/// "expand / collapse" list entry. When used with scrolling widgets like
/// [ListView], a unique [PageStorageKey] must be specified to enable the
/// [ExpansionTile] to save and restore its expanded state when it is scrolled
/// in and out of view.
///
/// See also:
///
///  * [ListTile], useful for creating expansion tile [children] when the
///    expansion tile represents a sublist.
///  * The "Expand/collapse" section of
///    <https://material.io/guidelines/components/lists-controls.html>.
class ExpansionTile extends StatefulWidget {

上面一段是 ExpansionTile 的源码注释。
粗略一看会发现几个熟悉的字眼:ListViewListTile
不错,实现层级菜单的效果,需要搭配使用ListView与ListTile,
上面贴的关键代码中 _buildItem()方法恰恰符合这一点,
当有子条目的时候返回ExpansionTile ,当没有子条目的时候返回 ListTile;

完整代码--->gihub


hosition
82 声望0 粉丝

这个人很懒,没写简介。。