APP 導航框架與常用功能實現
APP 首頁框架搭建
首先,先新建這些文件:
tab_navigator.dart 文件代碼如下:
import 'package:flutter/material.dart';
import 'package:xiecheng/pages/home_page.dart';
import 'package:xiecheng/pages/my_page.dart';
import 'package:xiecheng/pages/search_page.dart';
import 'package:xiecheng/pages/travel_page.dart';
class TabNavigator extends StatefulWidget {
@override
_TabNavigatorState createState() => _TabNavigatorState();
}
class _TabNavigatorState extends State<TabNavigator> {
final _defaultColor = Colors.grey;
final _activeColor = Colors.blue;
int _currentIndex = 0;
final PageController _controller = PageController(
initialPage: 0,
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _controller,
children: [
HomePage(),
MyPage(),
SearchPage(),
TravelPage(),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
_controller.jumpToPage(index);
setState(() {
_currentIndex = index;
});
},
type: BottomNavigationBarType.fixed, //把lable進行固定
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,
),
),
),
],
),
);
}
}
home_page.dart 文件代碼如下:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('首頁'),
),
);
}
}
my_page.dart 文件代碼如下:
import 'package:flutter/material.dart';
class MyPage extends StatefulWidget {
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('我的'),
),
);
}
}
search_page.dart 文件代碼如下:
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('搜索'),
),
);
}
}
travel_page.dart 文件代碼如下:
import 'package:flutter/material.dart';
class TravelPage extends StatefulWidget {
@override
TravelPageState createState() => TravelPageState();
}
class TravelPageState extends State<TravelPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('旅拍'),
),
);
}
}
最後將 main.dart 的代碼進行微小的修改:
就可以運行啦:
輪播圖 Banner 功能開發
輪播圖需要用到的 swiper 插件,我們可以去 pub 網站上去找:
打開 pub 網站,搜索 swiper 即可:
這時候我們查看該插件的 Installing,裏面會告訴你如何引入該插件:
這時候我們按照它說的步驟做就好啦:
引入後 VSCode 的右上角會出現一個下載的標誌,點擊下載即可;
然後編輯 home_page.dart 裏的代碼:
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List _imageUrls = [
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1976529436,2778459069&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3597917999,2966077325&fm=26&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3352739916,685169444&fm=26&gp=0.jpg',
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Container(
height: 160,
child: Swiper(
itemCount: _imageUrls.length,
autoplay: true,
itemBuilder: (BuildContext context, int index) {
return Image.network(
_imageUrls[index],
fit: BoxFit.fill,
);
},
pagination: SwiperPagination(),
),
),
],
),
),
);
}
}
運行界面如下:
自定義 AppBar 實現滾動漸變
修改 home_page.dart 的代碼,如下:
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
const APPBAR_SCROLL_OFFSET = 100; //設置滾動最大距離
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List _imageUrls = [
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1976529436,2778459069&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3597917999,2966077325&fm=26&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3352739916,685169444&fm=26&gp=0.jpg',
];
double appBarAlpha = 0.0;
_onScroll(offset) {
double alpha = offset / APPBAR_SCROLL_OFFSET;
if (alpha < 0.0) {
alpha = 0.0;
} else if (alpha > 1.0) {
alpha = 1.0;
}
setState(() {
appBarAlpha = alpha;
});
// print(appBarAlpha);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
MediaQuery.removePadding(
//把頂部預留的安全區域去掉
removeTop: true,
context: context,
child: NotificationListener(
//監聽列表的滾動
onNotification: (scrollNotification) {
if (scrollNotification is ScrollUpdateNotification &&
scrollNotification.depth == 0) {
//滾動且是列表滾動的時候
_onScroll(scrollNotification.metrics.pixels);
}
},
child: ListView(
children: [
Container(
height: 160,
child: Swiper(
itemCount: _imageUrls.length,
autoplay: true,
itemBuilder: (BuildContext context, int index) {
return Image.network(
_imageUrls[index],
fit: BoxFit.fill,
);
},
pagination: SwiperPagination(),
),
),
Container(
height: 800,
child: ListTile(
title: Text('阿巴阿巴阿巴'),
),
),
],
),
),
),
Opacity(
//自定義AppBar
opacity: appBarAlpha,
child: Container(
height: 80,
decoration: BoxDecoration(color: Colors.white),
child: Center(
child: Padding(
padding: EdgeInsets.only(top: 20),
child: Text('首頁'),
),
),
),
)
],
),
);
}
}
運行界面: