BottomNavigationBar结合TabBar实现类似头条框架
源码传送门
源码传送门gitee
效果图
1.实现底部BottomNavigationBar
Tabs.dart
import 'package:flutter/material.dart';
import 'package:newsscaffold/pages/tabs/Ixigua.dart';
import 'package:newsscaffold/pages/tabs/User.dart';
import 'package:newsscaffold/pages/tabs/VideoHall.dart';
import 'tabs/Home.dart';
class Tabs extends StatefulWidget {
final index;
Tabs({Key key,this.index=0}):super(key:key);
@override
_TabsState createState() => _TabsState(this.index);
}
class _TabsState extends State {
_TabsState(index){
this._currentIndex=index;
}
int _currentIndex ;
List _pageList = [HomePage(), IxiguaPage(), VideoHallPage(),UserPage()];
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// // Here we take the value from the MyHomePage object that was created by
// // the App.build method, and use it to set our appbar title.
// title: Text("今日头条"),
// ),
body: this._pageList[this._currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: this._currentIndex,
//图标大小
iconSize: 35,
//选中颜色
fixedColor: Colors.redAccent,
//底部可以设置多个按钮
type: BottomNavigationBarType.fixed,
onTap: (index) {
setState(() {
this._currentIndex = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
BottomNavigationBarItem(icon: Icon(Icons.play_arrow), title: Text("西瓜视频")),
BottomNavigationBarItem(icon: Icon(Icons.slideshow), title: Text("放映厅")),
BottomNavigationBarItem(icon: Icon(Icons.account_circle), title: Text("我的")),
]), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Tabs.dart中的四个页面
2.Home.dart 将TabBar放在AppBar的title中
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State with SingleTickerProviderStateMixin{
List _tabs = [
Tab(
text: "关注",
),
Tab(
text: "推荐",
),
Tab(
text: "热榜",
),
Tab(
text: "科技",
),
Tab(
text: "免费小说",
),
Tab(
text: "新时代",
),
Tab(
text: "抗疫",
),
Tab(
text: "问答",
),
Tab(
text: "数码",
),
Tab(
text: "要闻",
),
Tab(
text: "视频",
),
];
List _tabBars = [Center(
child: Text('关注'),
),
Center(
child: Text('推荐'),
),
Center(
child: Text('热榜'),
),
Center(
child: Text('科技'),
),
Center(
child: Text('免费小说'),
),
Center(
child: Text('新时代'),
),
Center(
child: Text('抗疫'),
),
Center(
child: Text('问答'),
),
Center(
child: Text('数码'),
),
Center(
child: Text('要闻'),
),
Center(
child: Text('视频'),
),];
TabController _tabController;//注意 在TabBar和TabBarView中都需要配置controller
@override
void initState() {
super.initState();
_tabController = new TabController(vsync: this, length: this._tabs.length);
_tabController.index=1;
setState(() {
});
//监听器
_tabController.addListener(() {
//点击切换tab的时候执行了一个动画效果,滑动切换的时候是没有的,在这个过程中触发了一次Listener,所以触发了两次addListener方法
// 解决点击tab执行2次的问题
if(_tabController.index ==_tabController.animation.value) {
//实现自定义的功能
print(_tabController.index);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: TabBar(
controller: this._tabController,
indicatorColor: Colors.redAccent,
labelColor: Colors.redAccent,
unselectedLabelColor: Colors.black,
isScrollable: true,
//和文字等宽
indicatorSize: TabBarIndicatorSize.label,
tabs: this._tabs,
),
),
body: TabBarView(children: this._tabBars,controller: this._tabController,),
);
}
}
Ixigua.dart
import 'package:flutter/material.dart';
class IxiguaPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('西瓜视频'),
);
}
}
VideoHall.dart
import 'package:flutter/material.dart';
class VideoHallPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('放映厅'),
);
}
}
User.dart
import 'package:flutter/material.dart';
class UserPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('我的'),
);
}
}
程序入口
main.dart
import 'package:flutter/material.dart';
import 'pages/Tabs.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
home: Tabs(index: 0,),
);
}
}