Tabbar 实现
- Scaffold 里有bottomNavigationBar属性,直接在这里设置即可.
- 通过IndexedStack 来设置切换的tab下的页面
- BottomNavigationBar 下的type, 如果tab数量 >= 4, 必须设置为Fixed, 不如出现底部一片白
- 具体代码实现如下:
![]()
1. main.dart
import 'package:flutter/material.dart';
import 'package:flutter_tabbar/Social.dart';
import 'package:flutter_tabbar/home.dart';
import 'package:flutter_tabbar/mall.dart';
import 'package:flutter_tabbar/user.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '首页',
// theme: ThemeData.dark(),
home: Content(),
);
}
}
class Content extends StatefulWidget {
@override
_ContentState createState() => _ContentState();
}
class _ContentState extends State<Content> {
var _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tabbar'),
backgroundColor: Colors.teal[900],
brightness: Brightness.dark,
),
bottomNavigationBar: _createBottomNavigationBarWidget(),
body: new IndexedStack(
index: _selectedIndex,
children: [
HomePage(),
MallPage(),
SocialPage(),
UserPage(),
],
),
);
}
_createBottomNavigationBarWidget() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed, // 超过4个必须设置fixed,否则底部一片白
currentIndex: _selectedIndex,
onTap: (index) {
if (_selectedIndex == index) return;
setState(() {
_selectedIndex = index;
});
print('index: $index');
},
items: [
_createItem(Icon(Icons.home), '首页'),
_createItem(Icon(Icons.local_mall), '商城'),
_createItem(Icon(Icons.social_distance), '社交'),
_createItem(Icon(Icons.person), '我的'),
],
);
}
BottomNavigationBarItem _createItem(Widget iconData, String labelTitle) {
return BottomNavigationBarItem(icon: iconData, label: labelTitle);
}
}
2. home.dart
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
return ListTile(
// tileColor: Colors.grey[200], // 如果设置背景色、请包裹一层Container设置decoration即可.
title: Text('item$index'),
subtitle: Text('description$index'),
leading: Icon(Icons.phone, size: 30),
);
},
separatorBuilder: (BuildContext context, int index) {
return Divider(
color: Colors.grey[350],
);
},
itemCount: 20,
);
}
}
3. mall.dart
import 'package:flutter/material.dart';
class MallPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.builder(
padding: EdgeInsets.all(10),
itemCount: 31,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.0,
),
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.grey[300],
alignment: Alignment(0, 0),
child: Text('item$index'),
);
},
);
}
}
4. social.dart
import 'package:flutter/material.dart';
class SocialPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.separated(
itemCount: 15,
separatorBuilder: (BuildContext context, int index) {
return Divider(
color: Colors.grey[400],
height: 1,
);
},
itemBuilder: (BuildContext context, int index) {
return Container(
height: 400,
alignment: Alignment(0, 0),
color: Colors.grey[200],
child: Text('item$index'),
);
},
);
}
}
5. user.dart
import 'package:flutter/material.dart';
class UserPage extends StatelessWidget {
final List<String> leftTitles = ['用户订单', '用户收藏', '个人中心', '清除缓存', '退出登录'];
final List<IconData?> leftIcons = [
Icons.local_mall,
Icons.save,
Icons.center_focus_strong,
Icons.cached,
Icons.logout,
];
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
// HeaderView
// https://588ku.com/tuku/kejixiantiao.html
// https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg
SliverAppBar(
expandedHeight: 250,
flexibleSpace: FlexibleSpaceBar(
title: Text('Wike Spiken'),
background: Image(
image: NetworkImage('https://588ku.com/tuku/kejixiantiao.html'),
fit: BoxFit.cover,
),
),
),
// ListView
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return _getSliverFixedExtentListWidget(context, index);
},
childCount: 5,
),
itemExtent: 60,
),
],
);
}
/* // ListTile无法设置分割线、只能自定义.
_getListTileWidget() {
return Container(
decoration: BoxDecoration(
color: Colors.grey[200],
),
child: ListTile(
// tileColor: Colors.grey[200], // !!!这个设置有bug,每个tabbar页面都会出现这个颜色
title: Text(leftTitles[index]),
leading: Icon(leftIcons[index], size: 25),
trailing: Icon(Icons.arrow_forward_ios, size: 15),
minLeadingWidth: 10,
),
);
}
*/
_getSliverFixedExtentListWidget(BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
color: Colors
.grey[200], //index % 2 == 0 ? Colors.green[200] : Colors.green,
),
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: [
Spacer(), // 尽可能大的间距
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 20),
Icon(leftIcons[index], size: 25),
SizedBox(width: 10),
Text(leftTitles[index]),
Spacer(), // 尽可能大的间距
Icon(Icons.arrow_forward_ios, size: 15),
SizedBox(width: 15),
],
),
Spacer(), // 尽可能大的间距
// 自定义分割线
Container(
width: MediaQuery.of(context).size.width,
height: 1,
color: Colors.grey[300],
),
],
),
);
}
}