Flutter 切换标签显示对应的列表+Provide状态管理实例

功能需求是顶部是三个展示数据区,下面是切换标签显示相对应的列表内容,其中有个别分类的布局还是不一样的。

效果图:

新建dart文件,引入数据模型文件和provide文件等:

class TszbPage extends StatefulWidget {
  _TszbPageState createState() => _TszbPageState();
}

class _TszbPageState extends State<TszbPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('庭审直播')),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            TszbTop(),
            TszbList(),
          ],
        )
      ),
var tszbListProvide = TszbListProvide();

..provide(Provider<TszbListProvide>.value(tszbListProvide));



    );
  }
}

还要记得在main.dart文件里引入

import './provide/tszb_list.dart';

然后添加Provide代码:

var tszbListProvide = TszbListProvide();

..provide(Provider<TszbListProvide>.value(tszbListProvide));

TszbTop顶部展板代码,由于只是显示数据,所以直接用了setState:

//顶部展板
class TszbTop extends StatefulWidget {
  _TszbTopState createState() => _TszbTopState();
}

class _TszbTopState extends State<TszbTop> {
  String todayLiveCount;
  String zgyLiveCount; 
  String viewCount;

  @override
  void initState() {
    super.initState();
    _getTop();
  }

  void _getTop() {
    var formData = {'isDebug': 'aa'};
    request('get', 'tszbTop', formData: formData).then((val) {
      var data = val.toString();
      //print(data);
      setState(() {
        todayLiveCount = (val['data']['todayLiveCount']).toString();
        zgyLiveCount = (val['data']['zgyLiveCount']).toString();
        viewCount = (val['data']['viewCount']).toString();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: ScreenUtil().setHeight(130),
      margin: EdgeInsets.only(top: 15),
      child: Row(
        children: <Widget>[
          _topItem('今日累计直播', '${todayLiveCount}'),
          _topItem('最高法院累计直播', '${zgyLiveCount}'),
          _topItem('全国累计直播', '${viewCount}')
        ],
      ),
    );
  }

  Widget _topItem(String title, String number){
    return Container(
      margin: EdgeInsets.fromLTRB(14, 0, 5, 0),
      padding: EdgeInsets.fromLTRB(5, 3, 5, 3),
       ScreenUtil().setWidth(210),
      height: ScreenUtil().setHeight(130),
      decoration: BoxDecoration(
 color: Colors.green,
     borderRadius: BorderRadius.circular(8.0),
), child: Column( children:
<Widget>[ Container( alignment: Alignment.centerLeft, child: Text('${number}件', style: TextStyle(color: Colors.white)), ), Container( padding: EdgeInsets.only(top: 15), alignment: Alignment.bottomRight, child: Text(title, style: TextStyle(color: Colors.white,fontSize:ScreenUtil().setSp(22))), ) ], ), ); } }

下面切换标签列表代码:

//下面标签列表
class TszbList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        TabsBar(),
        TabsList()
      ],
    );
  }
}

 标签代码:

class TabsBar extends StatefulWidget {
  _TabsBarState createState() => _TabsBarState();
}

class _TabsBarState extends State<TabsBar> {
  List tabs = [{"title":"案件观看量","type":"tszbGkl"},{"title":"最热门案件分类","type":"tszbAjfl"},
  。。。
  ];
  var listIndex = 0; //索引

  @override
  void initState() { 
    _getTabView(tabs[0]['type']); //首次加载
    super.initState();
  }

  void _getTabView(String type) {
    var formData = {'isDebug': 'aa'};
    request('get', type, formData: formData).then((val) {
      var data = val.toString();
      print(type);

      if(type == 'tszbAjfl'){ //当切换到tszbAjfl标签时,运行getOtherList,否则getGoodsList
        TszbOhterModel otherList = TszbOhterModel.fromJson(val);
        Provide.value<TszbListProvide>(context).getOtherList(otherList.data);
      }else{
        TszbListModel goodsList = TszbListModel.fromJson(val);
        Provide.value<TszbListProvide>(context).getGoodsList(goodsList.data);
      }
    });
  } 

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(top: 15),
      padding: EdgeInsets.fromLTRB(15, 5, 10, 5),
      height: ScreenUtil().setHeight(70),
      color: Colors.white,
      child: ListView.builder(
        scrollDirection: Axis.horizontal, //横向
        itemCount: tabs.length,
        itemBuilder: (context,index){
        return _tabInkWell(index);
      }, 
    ),
    );
  }
  //标签子项
  Widget _tabInkWell(int index){
    bool isClick = false; //是否点击了
    isClick = (index==listIndex) ? true : false; //判断当前点击的索引是否为全局变量的索引
    return InkWell(
      onTap: (){
        var type = tabs[index]['type'];
        setState(() {
          listIndex = index; //每次点击了大类就把索引赋值给listIndex
        });
        if(type == 'tszbAjfl'){ //改变type存储到Provide
          Provide.value<TszbListProvide>(context).changeTabs('hot');
        }else{
          Provide.value<TszbListProvide>(context).changeTabs('normal');
        }
        _getTabView(type);
      },
      child: Container(
        margin: EdgeInsets.only(right: 20),
        height: ScreenUtil().setHeight(100),
        decoration: BoxDecoration(
          border: isClick ? Border(bottom: BorderSide( 1,color: Colors.blueGrey)):Border(),
        ),
        child: Text(
          tabs[index]['title'],
          style: TextStyle(fontSize: ScreenUtil().setSp(28),color:isClick ? Colors.blueGrey:Colors.black,)
        ),
      ),
    );  
  }  
}

列表代码:

//列表
class TabsList extends StatefulWidget {
  _TabsListState createState() => _TabsListState();
}

class _TabsListState extends State<TabsList> {
  //List list = [];

  @override
  Widget build(BuildContext context) {
    return Provide<TszbListProvide>(
      builder: (context,child,data){
        var isTabs = Provide.value<TszbListProvide>(context).isTabs;
        //print(isTabs);

        return Container(
          height: ScreenUtil().setHeight(920),
          color: Colors.white,
          child: ListView.builder(
            itemCount: isTabs?data.otherList.length:data.goodsList.length,
            itemBuilder: (context, index) {

              if(isTabs){
                return _otherInkWell(data.otherList,index);
              }else{
                return _itemInkWell(data.goodsList,index);
              }
            },
          ), 
        );
      },
    );
  }
  //最热门案件分类列表组合
  Widget _otherInkWell(List newList,index){
    return  InkWell(
      onTap: (){},
      child: Container(
        margin: EdgeInsets.fromLTRB(13, 13, 13, 0),
        padding: EdgeInsets.only(bottom: 15),
        decoration: BoxDecoration(
          border: Border(
            bottom: BorderSide( 1,color: Colors.black12)
          )
        ),
        child: _otherItem(newList, index)
      ),
    );
  }
  //最热门案件分类子项
  Widget _otherItem(List newList,index){
    return Row(
      children: <Widget>[
        Container(
          alignment: Alignment.center,
          margin: EdgeInsets.only(right: 5),
           ScreenUtil().setWidth(35),
          height: ScreenUtil().setHeight(35),
          color: index<3 ? Colors.blueGrey : Colors.grey,
          child: Text('${index+1}',style: TextStyle(color: Colors.white)),
        ),
        Expanded(
          child: Text(newList[index].labelName),
        ),
        Text('${newList[index].caseCount}件'),
      ],
    );
  }
  //普通分类列表组合
  Widget _itemInkWell(List newList,index){
    return InkWell(
      onTap: (){},
      child: Container(
        margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
        padding: EdgeInsets.only(bottom: 15),
        decoration: BoxDecoration(
          border: Border(
            bottom: BorderSide( 1,color: Colors.black12)
          )
        ),
        child: Row(
          children: <Widget>[
            _itemVideo(newList,index),
            _itemRight(newList,index),
          ],
        ),
      ),
    );
  }
  //普通分类列表图片
  Widget _itemVideo(List newList,index){
    return Stack(
      children: <Widget>[
        Container(
           ScreenUtil().setWidth(250),
          child: Image.network(newList[index].videoThumbnail),
        ),
        Positioned(
          top: 0,
          left: 0,
          child:Container(
            alignment: Alignment.center,
             ScreenUtil().setWidth(35),
            height: ScreenUtil().setHeight(35),
            color: index<3 ? Colors.blueGrey : Colors.grey,
            child: Text(
              '${index+1}',
              style: TextStyle(color: Colors.white)
             ),
          ),
        ),
        Positioned(
          bottom: 0,
          right:5,
          child:Text(
            newList[index].formattedVideoDuration != null ? newList[index].formattedVideoDuration : '',
            style: TextStyle(color: Colors.white)
          ),
        ),
        
      ],
    );
  }
  //普通分类列表右侧文字
  Widget _itemRight(List newList,index){
    return Column(
      children: <Widget>[
        Container(
           ScreenUtil().setWidth(430),
          margin: EdgeInsets.only(left:8,bottom: 15),
          child:Text(
            newList[index].title,
            maxLines:2,
            overflow:TextOverflow.ellipsis,
          ),
        ),
        Container(
           ScreenUtil().setWidth(430),
          margin: EdgeInsets.only(left:8),
          alignment: Alignment.bottomLeft,
          child: Text(
            newList[index].courtName,
            style: TextStyle(color: Colors.black38,fontSize: ScreenUtil().setSp(22)),
          ),
        )
      ],
    );
  }

}
原文地址:https://www.cnblogs.com/joe235/p/11691006.html