1. Stack 层叠布局
Container(
color: Colors.grey,
margin: EdgeInsets.only(left: 10, right: 10),
height: 100,
child: Stack(
children: [
Positioned(
// Positioned用于嵌套于Stack容器,确定Positioned的布局到父容器四角的位置
child: Image.asset(
'images/lovely_girl.jpg',
width: 200.0,
fit: BoxFit.cover,
),
left: 10.0,
top: 20.0,
),
Positioned(
left: 10,
top: 20,
child: Text(
'Android进阶三步曲',
style: TextStyle(color: Colors.lightBlue, fontSize: 20),
),
)
],
),
)
2. Wrap 流式布局
Padding(
padding: EdgeInsets.all(0.0),
child: Wrap(
direction: Axis.horizontal, //主轴的方向
spacing: 4.0, //主轴方向的条目间距
runSpacing: -8.0, //副轴方向的条目间距
children: [
Chip(
label: Text('Android'),
),
Chip(
label: Text('iOS'),
),
Chip(
label: Text('Flutter'),
),
Chip(
label: Text('Kotlin'),
),
Chip(
label: Text('Kotlin'),
),
Chip(
label: Text('Kotlin'),
)
],
),
),
3. 抽屉布局
class _HomeDrawerPageState extends State<HomeDrawerPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.blue),
home: Scaffold(
appBar: AppBar(title: Text('抽屉布局'),),
body: Container(
child: Center(
child: Text('我的页面'),
),
),
drawer: DrawerSidePage() ,
),
);
}
}
4. Flex 布局
//Flutter中的弹性布局是Flex, 类似于Android中的FlexboxLayout。
//为了避免子Widget在Flex, Row, Column中超界,可以使用Flexible和Expanded,
//它们可以使Flex, Row, Column的子Widget具有弹性能力。
class CommonFlexPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('弹性布局'),),
body: Flex(
direction: Axis.horizontal,
children: [
Expanded(
flex: 1,
child: Container(height: 60.0, color: Colors.red,)),
Expanded(
flex: 3,
child: Container(height: 60.0, color: Colors.blue,)),
Expanded(
flex: 2,
child: Container(height: 60.0, color: Colors.green,)),
],
),
);
}
}
4. BottomNavigationBar+ PageView 类微信底部页面切换
import 'package:flutter/material.dart';
import 'package:flutter_widgets/layout/keep_alive_list.dart';
//TabBar+PageView用于构建底部TabBar+PageView的页面,常用于主页显示,类似微信这种主页
class TabBarPageNewView extends StatefulWidget {
@override
_TabBarPageViewState createState() => _TabBarPageViewState();
}
class _TabBarPageViewState extends State<TabBarPageNewView>
with TickerProviderStateMixin {
PageController _pageController;
final _defaultColor = Colors.grey;
final _activeColor = Colors.blue;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_pageController = PageController(initialPage: 0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PageView+TabBar页面'),
),
body: new PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
KeepAliveList(
title: '首页',
),
KeepAliveList(
title: '搜索',
),
KeepAliveList(
title: '旅拍',
),
KeepAliveList(
title: '我的',
),
],
),
bottomNavigationBar: _getBottomTabBarByType(),
);
}
//返回底部Tab
Widget _getBottomTabBarByType() {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _defaultColor,
),
activeIcon: Icon(
Icons.home,
color: _activeColor,
),
// ignore: deprecated_member_use
title: Text(
'首页',
style: TextStyle(
color: _currentIndex != 0 ? _defaultColor : _activeColor),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
color: _defaultColor,
),
activeIcon: Icon(
Icons.search,
color: _activeColor,
),
// ignore: deprecated_member_use
title: Text(
'搜索',
style: TextStyle(
color: _currentIndex != 1 ? _defaultColor : _activeColor),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.camera_alt,
color: _defaultColor,
),
activeIcon: Icon(
Icons.camera_alt,
color: _activeColor,
),
// ignore: deprecated_member_use
title: Text(
'旅拍',
style: TextStyle(
color: _currentIndex != 2 ? _defaultColor : _activeColor),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
color: _defaultColor,
),
activeIcon: Icon(
Icons.account_circle,
color: _activeColor,
),
// ignore: deprecated_member_use
title: Text(
'我的',
style: TextStyle(
color: _currentIndex != 3 ? _defaultColor : _activeColor),
),
),
],
currentIndex: _currentIndex,
onTap: (index) {
_pageController.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
type: BottomNavigationBarType.fixed, // label 永远显示
);
}
@override
void dispose() {
super.dispose();
_pageController.dispose();
}
}
import 'package:flutter/material.dart';
class KeepAliveList extends StatefulWidget {
final String title;
KeepAliveList({Key key, this.title}) : super(key: key);
@override
_KeepAliveListState createState() => _KeepAliveListState(title);
}
class _KeepAliveListState extends State<KeepAliveList>
with AutomaticKeepAliveClientMixin {
var title;
_KeepAliveListState(String title) {
this.title = title;
}
@override
Widget build(BuildContext context) {
super.build(context);
return Container(
child: RefreshIndicator(
onRefresh: _handleOnRefresh,
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: double.infinity,
height: 40,
margin: EdgeInsets.fromLTRB(10, 5, 10, 5),
alignment: Alignment.center,
color: Colors.blue,
child: Text(
'$title $index',
style: TextStyle(color: Colors.white),
),
);
}),
),
);
}
Future<Null> _handleOnRefresh() async {
await Future.delayed(Duration(seconds: 2));
return null;
}
@override
bool get wantKeepAlive => true; //保存页面状态
}
5. 顶部Tab+PageView 类似头条顶部分类显示
注意:如果不实现AutoKeepAliveClientMixin接口,那么就会出现再次返回列表之后,列表会自动的滑动到第一项,也就是说页面的状态无法保持住,所以为了保持页面状态,要实现这个接口,并将 wantKeepAlive 方法返回 true, 其次,还要将 build() 方法中的第一行调用 super.build(context);
import 'package:flutter/material.dart';
import 'package:flutter_widgets/layout/keep_alive_list.dart';
//顶部TabBar+TabBarView 组成的页面
class TabBarTabBarViewPage extends StatefulWidget {
@override
_TabBarTabBarViewPageState createState() => _TabBarTabBarViewPageState();
}
class _TabBarTabBarViewPageState extends State<TabBarTabBarViewPage>
with TickerProviderStateMixin {
TabController _tabController;
List<String> myTabs = [
'Kotlin',
'Flutter',
'C',
'C++',
'Android',
'Flutter',
'iOS '
];
@override
void initState() {
super.initState();
_tabController = new TabController(length: myTabs.length, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false, // 取消向左的箭头
title: TabBar(
isScrollable: true,
controller: _tabController,
tabs: myTabs
.map((title) => Tab(
text: title,
))
.toList(),
indicatorColor: Colors.blue,
indicatorWeight: 4.0, // indicator的宽度
//automaticIndicatorColorAdjustment: true,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab, // indicator的长度 .tab是等分宽度 .label是和名字一样宽
),
),
body: TabBarView(
controller: _tabController,
children: myTabs.map((item) => KeepAliveList(title: item)).toList()),
);
}
@override
void dispose() {
super.dispose();
_tabController.dispose();
}
}