Flutter 入口页面及底部导航栏实例制作
cupertino_IOS风格介绍
在Flutter里是有两种内置风格的:
- material风格: Material Design 是由Google推出的全新设计语言,这种设计语言是为手机、平板电脑、台式机和其他平台提供一致,更广泛的外观和感觉。我喜欢称它为纸墨设计。Material Design 风格是一种非常有质感的设计风格,并会提供一些默认的交互动画。
- cupertino风格:即IOS风格组件,它重现了很多经典的有IOS特性的交互和界面风格,让适用于IOS的人感觉亲切和友好。
有些小伙伴误认为你的APP选择了一种风格,就要一直使用这种风格,但事实是你可以一起使用,兼顾两个风格的特点,比如这里就觉得cupertino风格的图标比较细致和美观。所以在index_page.dart
页面,先引入了cupertino.dart
,然后又引入了material.dart
。当然这两个引入是不分先后顺序的。
import ‘package:flutter/cupertino.dart‘; import ‘package:flutter/material.dart‘;
使用动态StatefulWidget
因为底部导航栏是要根据用户操作不断变化的,所以我们使用动态组件(StatefulWidget
)。
class IndexPage extends StatefulWidget { _IndexPageState createState() => _IndexPageState(); } class _IndexPageState extends State<IndexPage> { @override Widget build(BuildContext context) { return Container( child: child, ); } }
bottomTabs List
有了动态组件,接下来可以在State
部分先声明一个List变量,变量名称为boottomTabs
。这个变量的属性为BottomNavigationBarItem
。
其实这个List变量就定义了底部导航的文字和使用的图标。
代码如下:
final List<BottomNavigationBarItem> bottomTabs = [ BottomNavigationBarItem( icon:Icon(CupertinoIcons.home), title:Text(‘首页‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.search), title:Text(‘分类‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.shopping_cart), title:Text(‘购物车‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.profile_circled), title:Text(‘会员中心‘) ), ];
新建四个基本dart文件
在pages
目录下,我们新建下面四个dart
文件。
- home_page.dart :商城首页UI页面,首页相关的UI我们都会放到这个文件里。
- category_page.dart: 商城分类UI页面,这个页面会有复杂的动态组件切换。
- cart_page.dart:商城购物车UI页面,这个页面会包括购物车的全套功能。
- member_page.dart:商城会员中心页面,这个页面我们会制作会员中心的全部UI效果。
其实这一部就是建立了底部导航栏需要的四个基本页面,有了这四个基本页面就可以制作底部tab的切换功能了。
页面(home_page.dart)的基础代码,复制到其它页面,进行修改。
import ‘package:flutter/material.dart‘; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body:Center( child: Text(‘商城首页‘), ) ); } }
记得其他三个页面都进行复制,并修改类名和Text文本属性。
引入页面并建立List
页面创建好以后,要使用import
引入到index_page.dart
中,引入后才可以使用,如果不引入,VScode
会很智能的报错。代码如下。
import ‘home_page.dart‘; import ‘category_page.dart‘; import ‘cart_page.dart‘; import ‘member_page.dart‘;
引入后声明一个List型变量,这个变量主要用于切换的,我们把页面里的类,放到了这个List中。
final List tabBodies = [ HomePage(), CategoryPage(), CartPage(), MemberPage() ];
声明两个变量,并进行initState
初始化:
- currentIndex: int类型,负责tabBodies的List索引,改变索引就相当于改变了页面。
- currentPage: 利用
currentIndex
得到当前选择的页面,并进行呈现出来。
代码如下:
int currentIndex = 0; //当前索引 var currentPage; //对应类的变量 @override void initState() { //初始化 currentPage = tabBodies[currentIndex]; //默认0 首页 super.initState(); }
build方法的编写
build
方法我们会返回一个Scaffold
部件,在部件里我们会添加底部导航栏,并利用onTap事件(单击事件),来改变导航栏的状态和切换页面。因为有界面变化,所以这也是要使用动态组件的原因。
@override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color.fromRGBO(244, 245, 245, 1.0), bottomNavigationBar: BottomNavigationBar( type:BottomNavigationBarType.fixed, currentIndex: currentIndex, items:bottomTabs, onTap: (index){ setState(() { currentIndex = index; currentPage = tabBodies[currentIndex]; }); }, ), body:currentPage ); }
这里有句代码type:BottomNavigationBarType.fixed
,这个是设置底部tab的样式,它有两种样式fixed
和shifting
,只有超过3个才会有区别,国人的习惯一般是使用fixed
的。感兴趣的小伙伴可以自行折腾shifting
模式。
这时候就可以启动虚拟机,进行预览了。
index_page.dart完整代码:
import ‘package:flutter/cupertino.dart‘; import ‘package:flutter/material.dart‘; import ‘home_page.dart‘; import ‘category_page.dart‘; import ‘cart_page.dart‘; import ‘member_page.dart‘; class IndexPage extends StatefulWidget { _IndexPageState createState() => _IndexPageState(); } class _IndexPageState extends State<IndexPage> { final List<BottomNavigationBarItem> bottomTabs = [ BottomNavigationBarItem( icon:Icon(CupertinoIcons.home), title:Text(‘首页‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.search), title:Text(‘分类‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.shopping_cart), title:Text(‘购物车‘) ), BottomNavigationBarItem( icon:Icon(CupertinoIcons.profile_circled), title:Text(‘会员中心‘) ), ]; final List tabBodies = [ HomePage(), CategoryPage(), CartPage(), MemberPage() ]; int currentIndex = 0; //当前索引 var currentPage; //对应类的变量 @override void initState() { //初始化 currentPage = tabBodies[currentIndex]; //默认0 首页 super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color.fromRGBO(244, 245, 245, 1.0), bottomNavigationBar: BottomNavigationBar( type:BottomNavigationBarType.fixed, currentIndex: currentIndex, items:bottomTabs, onTap: (index){ setState(() { currentIndex=index; currentPage =tabBodies[currentIndex]; }); }, ), body: currentPage, ); } }