天天看點

Flutter 左右菜單關聯

效果:

Flutter 左右菜單關聯
Flutter 左右菜單關聯
像這種左右菜單關聯的效果很常見,即點選左邊菜單清單右邊重新整理,這裡示範一下在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