Flutter 左右菜单联动

    xiaoxiao2022-07-05  154

    效果:

    像这种左右菜单联动的效果很常见,即点击左边菜单列表右边刷新,这里演示一下在Flutter中的实现

    页面结构

    很简单,分为左右结构,左边是一个ListView,右边也是一个ListView,然后按比例显示即可

    return new Row( mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ new Expanded( flex: 2, child: Container( color: YColors.color_fff, child: new ListView.builder( itemCount: _datas.length, itemBuilder: (BuildContext context, int position) { return getRow(position); }), )), new Expanded( flex: 5, child: ListView( children: <Widget>[ Container( //height: double.infinity, alignment: Alignment.topLeft, padding: const EdgeInsets.all(10), color: YColors.color_f3f3f3, child: getChip(index), //传入一级分类下标 ), ], )), ], );

    这里用到Expanded,flex参数等同于Android中的权重。

    然后把两个ListView的item构建抽出来了。

    左边item getRow:

    Widget getRow(int i) { return new GestureDetector( child: new Container( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 15, horizontal: 10), color: Colors.white, child: new Text(_datas[i].name, style: TextStyle( color: YColors.color_666, fontSize: 16)), ), onTap: () { setState(() { }); }, ); }

    很简单,就是一个text显示文字。

    右边item getChip:

    Widget getChip(int i) { return Wrap( spacing: 10.0, //两个widget之间横向的间隔 direction: Axis.horizontal, //方向 alignment: WrapAlignment.start, //内容排序方式 children: List<Widget>.generate( articles.length, (int index) { return ActionChip( //标签文字 label: Text(articles[index].title, style: TextStyle(fontSize: 16, color: YColors.color_666)), //点击事件 onPressed: () { }, elevation: 3, ); }, ).toList(), ); }

    item用的是Chip标签,Flutter Chip详解

    点击更新

    ok ,现在是左右两个列表都完成了(测试数据完全可以写死),那怎么做到点击左边的item 刷新右边的列表呢?

    在android 中可以用notifyDataSetChanged,在Flutter中,因为Widget 分为有状态(StatefulWidget)和无状态(StatelessWidget)的,所以要先继承自StatefulWidget,然后用setState方法更新数据源即可。

    所以我们单独写一个方法来更新数据:

    List<NaviDataArticle> _updateArticles(int i) { setState(() { if (_datas.length != 0) articles = _datas[i].articles; }); return articles; }

    接收一个int下标参数,根据一级分类下标更新二级分类集合。

    一般进来都是默认选中第一个菜单,可以在initState()方法中对这个一级分类下标进行初始化,一级分类下标index 默认为0

    setState(() { _datas = naviEntity.data; index = 0; });

    然后在一级分类列表的item点击事件中对一级分类index进行赋值,并修改选中item 的样式。

    Color textColor = YColors.colorPrimary; //字体颜色 Widget getRow(int i) { return new GestureDetector( child: new Container( alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 15, horizontal: 10), color: index == i ? YColors.color_f3f3f3 : Colors.white, child: new Text(_datas[i].name, style: TextStyle( color: index == i ? textColor : YColors.color_666, fontSize: 16)), ), onTap: () { setState(() { index = i; //记录选中的下标 textColor = YColors.colorPrimary; }); }, ); }

    然后右边列表在渲染之前,先更新数据

    Widget getChip(int i) { //更新对应下标数据 _updateArticles(i); return Wrap( ... ); }

    完整代码:https://github.com/yechaoa/wanandroid_flutter/blob/master/lib/pages/naviPage.dart

    yechaoa 认证博客专家 Android Jetpack Flutter 小程序 专注于Android领域,同时探索于大前端方向,研究并应用落地前端、小程序、Flutter、Kotlin等相关热门技术点
    最新回复(0)