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), width: 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(width: 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(width: 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), width: 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(width: 1,color: Colors.black12) ) ), child: Row( children: <Widget>[ _itemVideo(newList,index), _itemRight(newList,index), ], ), ), ); } //普通分类列表图片 Widget _itemVideo(List newList,index){ return Stack( children: <Widget>[ Container( width: ScreenUtil().setWidth(250), child: Image.network(newList[index].videoThumbnail), ), Positioned( top: 0, left: 0, child:Container( alignment: Alignment.center, width: 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( width: ScreenUtil().setWidth(430), margin: EdgeInsets.only(left:8,bottom: 15), child:Text( newList[index].title, maxLines:2, overflow:TextOverflow.ellipsis, ), ), Container( width: 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)), ), ) ], ); } }