APP首页框架搭建
- 实现首页导航需要哪些材料?
- 什么是Scaffold widget?
- 什么是PageView?
- 实现首页导航
实现首页导航需要哪些材料?
- Scaffold
-
- BottomNavigationBar
- PageView
-
- PageController
什么是Scaffold widget?
Scaffold
是一个实现了基本的material design
的布局结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Scaffold extends StatefulWidget { /// Creates a visual scaffold for material design widgets. const Scaffold({ Key key, this.appBar, this.body, this.floatingActionButton, this.floatingActionButtonLocation, this.floatingActionButtonAnimator, this.persistentFooterButtons, this.drawer, this.endDrawer, this.bottomNavigationBar, this.bottomSheet, this.backgroundColor, this.resizeToAvoidBottomPadding = true, this.primary = true, }) : assert(primary != null), super(key: key); |
顶部导航
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import 'package:flutter/material.dart'; class TabbedAppBarSample extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: DefaultTabController( length: choices.length, child: Scaffold( appBar: AppBar( title: const Text('Tabbed AppBar'), bottom: TabBar( isScrollable: true, tabs: choices.map((Choice choice) { return Tab( text: choice.title, icon: Icon(choice.icon), ); }).toList(), ), ), body: TabBarView( children: choices.map((Choice choice) { return Padding( padding: const EdgeInsets.all(16.0), child: ChoiceCard(choice: choice), ); }).toList(), ), ), ), ); } } class Choice { const Choice({this.title, this.icon}); final String title; final IconData icon; } const List<Choice> choices = const <Choice>[ const Choice(title: 'CAR', icon: Icons.directions_car), const Choice(title: 'BICYCLE', icon: Icons.directions_bike), const Choice(title: 'BOAT', icon: Icons.directions_boat), const Choice(title: 'BUS', icon: Icons.directions_bus), const Choice(title: 'TRAIN', icon: Icons.directions_railway), const Choice(title: 'WALK', icon: Icons.directions_walk), ]; class ChoiceCard extends StatelessWidget { const ChoiceCard({Key key, this.choice}) : super(key: key); final Choice choice; @override Widget build(BuildContext context) { final TextStyle textStyle = Theme.of(context).textTheme.display1; return Card( color: Colors.white, child: Center( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Icon(choice.icon, size: 128.0, color: textStyle.color), Text(choice.title, style: textStyle), ], ), ), ); } } void main() { runApp(TabbedAppBarSample()); } |
底部导航菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
import 'package:flutter/material.dart'; import 'package:flutter_app/pages/home_page.dart'; import 'package:flutter_app/pages/my_page.dart'; import 'package:flutter_app/pages/search_page.dart'; import 'package:flutter_app/pages/travel_page.dart'; class TabNavigator extends StatefulWidget { @override _TabNavigatorState createState() => _TabNavigatorState(); } class _TabNavigatorState extends State<TabNavigator> with SingleTickerProviderStateMixin { final _defaultColor = Colors.grey; final _activeColor = Colors.blue; int _currentIndex = 0; var _controller = PageController( initialPage: 0, ); @override void dispose() { super.dispose(); _controller.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: _controller, children: <Widget>[HomePage(), SearchPage(), TravelPage(), MyPage()], physics: NeverScrollableScrollPhysics(), ), bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, onTap: (index) { _controller.jumpToPage(index); setState(() { _currentIndex = index; }); }, type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( icon: Icon( Icons.home, color: _defaultColor, ), activeIcon: Icon( Icons.home, color: _activeColor, ), title: Text( '首页', style: TextStyle( color: _currentIndex != 0 ? _defaultColor : _activeColor), ), ), BottomNavigationBarItem( icon: Icon( Icons.search, color: _defaultColor, ), activeIcon: Icon( Icons.search, color: _activeColor, ), title: Text( '搜索', style: TextStyle( color: _currentIndex != 1 ? _defaultColor : _activeColor), )), BottomNavigationBarItem( icon: Icon( Icons.camera_alt, color: _defaultColor, ), activeIcon: Icon( Icons.camera_alt, color: _activeColor, ), title: Text( '旅拍', style: TextStyle( color: _currentIndex != 2 ? _defaultColor : _activeColor), )), BottomNavigationBarItem( icon: Icon( Icons.account_circle, color: _defaultColor, ), activeIcon: Icon( Icons.account_circle, color: _activeColor, ), title: Text( '我的', style: TextStyle( color: _currentIndex != 3 ? _defaultColor : _activeColor), )), ], ), ); } } |
侧拉栏菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final appTitle = 'Drawer Demo'; @override Widget build(BuildContext context) { return MaterialApp( title: appTitle, home: MyHomePage(title: appTitle), ); } } class MyHomePage extends StatelessWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title)), body: Center(child: Text('My Page!')), drawer: Drawer( // Add a ListView to the drawer. This ensures the user can scroll // through the options in the Drawer if there isn't enough vertical // space to fit everything. child: ListView( // Important: Remove any padding from the ListView. padding: EdgeInsets.zero, children: <Widget>[ DrawerHeader( child: Text('Drawer Header'), decoration: BoxDecoration( color: Colors.blue, ), ), ListTile( title: Text('Item 1'), onTap: () { // Update the state of the app // ... // Then close the drawer Navigator.pop(context); }, ), ListTile( title: Text('Item 2'), onTap: () { // Update the state of the app // ... // Then close the drawer Navigator.pop(context); }, ), ], ), ), ); } } |
什么是PageView?
PageView
是一个可以完成页面之间滚动的widget。 类似于Android中的ViewPager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class PageView extends StatefulWidget { PageView({ Key key, this.scrollDirection = Axis.horizontal, //滚动的方向,支持水平和垂直两个方向 this.reverse = false, //是否反方向滚动 PageController controller, //PageView的控制类 this.physics, //手势滚动逻辑,支持不滚动,总是滚动,与滚动到边缘时是否有bounce this.pageSnapping = true,//设置为false以禁用页面捕捉,对自定义滚动行为很有用。 this.onPageChanged,//页面切换时调用 List<Widget> children = const <Widget>[], }) : controller = controller ?? _defaultPageController, childrenDelegate = SliverChildListDelegate(children), super(key: key); ... |