柚子快報激活碼778899分享:Flutter 初識:導航控件
Flutter導航控件小結
路由與導航Navigator核心方法屬性示例基本導航示例替換當前頁面并推入新頁面使用命名路由動態(tài)生成路由額外的導航功能
完整示例代碼
MaterialPageRoute屬性示例
CupertinoPageRoute屬性示例
應用欄與底部導航AppBar屬性解析示例
BottomNavigationBar屬性解析示例
Drawer屬性解析示例
示例
路由與導航
Navigator
Navigator 用于管理應用程序的路由,通過堆棧結構來實現(xiàn)頁面的進出。它支持頁面的推入(push)和彈出(pop)操作,允許在應用中進行復雜的導航模式。
核心方法
Navigator.push: 將新頁面推入導航堆棧。Navigator.pop: 從導航堆棧中彈出當前頁面。Navigator.pushReplacement: 替換當前頁面,并將新頁面推入導航堆棧。Navigator.pushNamed: 使用命名路由推入新頁面。Navigator.popUntil: 彈出導航堆棧中的頁面直到滿足特定條件。Navigator.pushAndRemoveUntil: 推入新頁面并移除所有先前的頁面,直到滿足特定條件。Navigator.maybePop: 嘗試從導航堆棧中彈出當前頁面,如果沒有更多頁面可以彈出,則返回false。
屬性
initialRoute: 應用啟動時的初始路由。onGenerateRoute: 動態(tài)生成路由的回調函數(shù)。onUnknownRoute: 當無法找到匹配路由時調用的回調函數(shù)。
示例
基本導航示例
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
Navigator.pop(context);
替換當前頁面并推入新頁面
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
使用命名路由
定義命名路由:
void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstPage(),
'/second': (context) => SecondPage(),
},
));
}
使用命名路由導航:
Navigator.pushNamed(context, '/second');
動態(tài)生成路由
void main() {
runApp(MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == '/second') {
return MaterialPageRoute(
builder: (context) => SecondPage(),
);
}
// Define other routes here
assert(false, 'Need to implement ${settings.name}');
return null;
},
));
}
額外的導航功能
推入新頁面并移除所有先前的頁面,直到滿足特定條件
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
ModalRoute.withName('/'),
);
嘗試從導航堆棧中彈出當前頁面
bool popped = await Navigator.maybePop(context);
if (!popped) {
// Handle the case where there are no more pages to pop
}
完整示例代碼
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstPage(),
'/second': (context) => SecondPage(),
'/third': (context) => ThirdPage(),
},
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("First Page")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Text('Push to Second Page'),
),
ElevatedButton(
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Text('PushReplace to Second Page'),
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/third');
},
child: Text('Go to Third Page with Named Route'),
),
],
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Second Page")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context, 'Data from Second Page');
},
child: Text('Pop and Return Data'),
),
ElevatedButton(
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
child: Text('Pop Until First Page'),
),
ElevatedButton(
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => ThirdPage()),
ModalRoute.withName('/'),
);
},
child: Text('Push and Remove Until First Page'),
),
],
),
),
);
}
}
class ThirdPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Third Page")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Back to Previous Page'),
),
ElevatedButton(
onPressed: () async {
bool popped = await Navigator.maybePop(context);
if (!popped) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('No more pages to pop')),
);
}
},
child: Text('Maybe Pop'),
),
],
),
),
);
}
}
? ?
MaterialPageRoute
MaterialPageRoute 是一個材料設計風格的頁面路由,用于在安卓平臺上提供一致的導航體驗。它繼承自PageRoute,并且實現(xiàn)了TransitionRoute用于處理頁面切換時的過渡動畫。
屬性
builder: 構建路由頁面的回調函數(shù)。settings: 路由的配置信息,如名稱、參數(shù)等。maintainState: 是否在頁面離開視圖但未完全移除時保持狀態(tài)。fullscreenDialog: 是否將頁面展示為全屏對話框。
示例
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(),
settings: RouteSettings(name: '/second'),
),
);
在SecondPage中接收傳遞的參數(shù):
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final RouteSettings settings = ModalRoute.of(context)!.settings;
final String? data = settings.arguments as String?;
return Scaffold(
appBar: AppBar(title: Text("Second Page")),
body: Center(child: Text(data ?? 'No data')),
);
}
}
? ?
CupertinoPageRoute
CupertinoPageRoute 是一個iOS風格的頁面路由,用于在iOS平臺上提供一致的導航體驗。它同樣繼承自PageRoute,并實現(xiàn)了TransitionRoute用于處理頁面切換時的過渡動畫。
屬性
builder: 構建路由頁面的回調函數(shù)。settings: 路由的配置信息,如名稱、參數(shù)等。maintainState: 是否在頁面離開視圖但未完全移除時保持狀態(tài)。fullscreenDialog: 是否將頁面展示為全屏對話框。
示例
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => SecondPage(),
settings: RouteSettings(name: '/second'),
),
);
在SecondPage中接收傳遞的參數(shù):
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final RouteSettings settings = ModalRoute.of(context)!.settings;
final String? data = settings.arguments as String?;
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text("Second Page"),
),
child: Center(child: Text(data ?? 'No data')),
);
}
}
? ?
應用欄與底部導航
AppBar
AppBar 是頂部應用欄,通常用于顯示標題、導航按鈕等。
屬性解析
AppBar({
super.key,
this.leading,
this.automaticallyImplyLeading = true,
this.title,
this.actions,
this.flexibleSpace,
this.bottom,
this.elevation,
this.scrolledUnderElevation,
this.notificationPredicate = defaultScrollNotificationPredicate,
this.shadowColor,
this.surfaceTintColor,
this.shape,
this.backgroundColor,
this.foregroundColor,
this.iconTheme,
this.actionsIconTheme,
this.primary = true,
this.centerTitle,
this.excludeHeaderSemantics = false,
this.titleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
this.toolbarHeight,
this.leadingWidth,
this.toolbarTextStyle,
this.titleTextStyle,
this.systemOverlayStyle,
this.forceMaterialTransparency = false,
this.clipBehavior,
})
key:用于標識控件的唯一值。leading:可選參數(shù),類型為 Widget,表示前導控件,通常是導航圖標。automaticallyImplyLeading:可選參數(shù),類型為 bool,默認為 true,是否自動根據(jù)路由生成前導控件。title:可選參數(shù),類型為 Widget,表示標題控件。actions:可選參數(shù),類型為 List,表示操作控件列表,通常是一些圖標按鈕。flexibleSpace:可選參數(shù),類型為 Widget,表示靈活空間控件。bottom:可選參數(shù),類型為 PreferredSizeWidget,表示底部控件,通常是 TabBar。elevation:可選參數(shù),類型為 double,表示陰影高度。scrolledUnderElevation:可選參數(shù),類型為 double,表示滑動時的陰影高度。notificationPredicate:可選參數(shù),類型為 ScrollNotificationPredicate,表示通知謂詞。shadowColor:可選參數(shù),類型為 Color,表示陰影顏色。surfaceTintColor:可選參數(shù),類型為 Color,表示表面顏色。shape:可選參數(shù),類型為 ShapeBorder,表示形狀。backgroundColor:可選參數(shù),類型為 Color,表示背景顏色。foregroundColor:可選參數(shù),類型為 Color,表示前景顏色。iconTheme:可選參數(shù),類型為 IconThemeData,表示圖標主題。actionsIconTheme:可選參數(shù),類型為 IconThemeData,表示操作圖標主題。primary:可選參數(shù),類型為 bool,默認為 true,表示是否為主 AppBar。centerTitle:可選參數(shù),類型為 bool,表示標題是否居中。excludeHeaderSemantics:可選參數(shù),類型為 bool,表示是否排除頭部語義。titleSpacing:可選參數(shù),類型為 double,表示標題間距。toolbarOpacity:可選參數(shù),類型為 double,表示工具欄不透明度,默認為 1.0。bottomOpacity:可選參數(shù),類型為 double,表示底部控件不透明度,默認為 1.0。toolbarHeight:可選參數(shù),類型為 double,表示工具欄高度。leadingWidth:可選參數(shù),類型為 double,表示前導控件寬度。toolbarTextStyle:可選參數(shù),類型為 TextStyle,表示工具欄文字樣式。titleTextStyle:可選參數(shù),類型為 TextStyle,表示標題文字樣式。systemOverlayStyle:可選參數(shù),類型為 SystemUiOverlayStyle,表示系統(tǒng)覆蓋層樣式。forceMaterialTransparency:可選參數(shù),類型為 bool,表示是否強制材料透明度。clipBehavior:可選參數(shù),類型為 Clip,表示剪切行為。
示例
class ExamplePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () {
// handle menu button press
},
),
title: Text('AppBar Example'),
actions:
IconButton(
icon: Icon(Icons.search),
onPressed: () {
// handle search button press
},
),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {
// handle more button press
},
),
],
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(50.0),
child: Container(
color: Colors.orange,
height: 50.0,
child: Center(child: Text('Bottom Widget')),
),
),
elevation: 4.0,
backgroundColor: Colors.red,
foregroundColor: Colors.white,
centerTitle: true,
),
body: Center(child: Text('Hello, world!')),
),
);
}
}
? ?
BottomNavigationBar
BottomNavigationBar 是底部導航欄,用于在底部展示多個導航項。
屬性解析
BottomNavigationBar({
super.key,
required this.items, // 必需參數(shù),導航欄項列表
this.onTap, // 點擊事件回調
this.currentIndex = 0, // 當前選中的索引
this.elevation, // 陰影高度
this.type, // 導航欄類型
Color? fixedColor, // 固定顏色(已廢棄,請使用 selectedItemColor)
this.backgroundColor, // 背景顏色
this.iconSize = 24.0, // 圖標大小
Color? selectedItemColor, // 選中項顏色
this.unselectedItemColor, // 未選中項顏色
this.selectedIconTheme, // 選中圖標主題
this.unselectedIconTheme, // 未選中圖標主題
this.selectedFontSize = 14.0, // 選中標簽字體大小
this.unselectedFontSize = 12.0, // 未選中標簽字體大小
this.selectedLabelStyle, // 選中標簽樣式
this.unselectedLabelStyle, // 未選中標簽樣式
this.showSelectedLabels, // 是否顯示選中標簽
this.showUnselectedLabels, // 是否顯示未選中標簽
this.mouseCursor, // 鼠標指針樣式
this.enableFeedback, // 是否啟用反饋
this.landscapeLayout, // 橫向布局
this.useLegacyColorScheme = true, // 是否使用舊顏色方案
});
key:用于標識控件的唯一值。items:必需參數(shù),類型為 List,表示導航欄項列表。onTap:可選參數(shù),類型為 ValueChanged?,點擊事件回調,當導航欄項被點擊時調用。currentIndex:可選參數(shù),類型為 int,默認為 0,表示當前選中的索引。elevation:可選參數(shù),類型為 double?,表示陰影高度。type:可選參數(shù),類型為 BottomNavigationBarType?,表示導航欄類型,可以是 fixed 或 shifting。backgroundColor:可選參數(shù),類型為 Color?,表示背景顏色。iconSize:可選參數(shù),類型為 double,表示圖標大小,默認為 24.0。selectedItemColor:可選參數(shù),類型為 Color?,表示選中項顏色。unselectedItemColor:可選參數(shù),類型為 Color?,表示未選中項顏色。selectedIconTheme:可選參數(shù),類型為 IconThemeData?,表示選中圖標主題。unselectedIconTheme:可選參數(shù),類型為 IconThemeData?,表示未選中圖標主題。selectedFontSize:可選參數(shù),類型為 double,表示選中標簽字體大小,默認為 14.0。unselectedFontSize:可選參數(shù),類型為 double,表示未選中標簽字體大小,默認為 12.0。selectedLabelStyle:可選參數(shù),類型為 TextStyle?,表示選中標簽樣式。unselectedLabelStyle:可選參數(shù),類型為 TextStyle?,表示未選中標簽樣式。showSelectedLabels:可選參數(shù),類型為 bool?,表示是否顯示選中標簽。showUnselectedLabels:可選參數(shù),類型為 bool?,表示是否顯示未選中標簽。mouseCursor:可選參數(shù),類型為 MouseCursor?,表示鼠標指針樣式。enableFeedback:可選參數(shù),類型為 bool?,表示是否啟用反饋。landscapeLayout:可選參數(shù),類型為 BottomNavigationBarLandscapeLayout?,表示橫向布局方式。useLegacyColorScheme:可選參數(shù),類型為 bool,表示是否使用舊顏色方案,默認為 true。
示例
class BottomPage extends StatefulWidget {
@override
_BottomPageState createState() => _BottomPageState();
}
class _BottomPageState extends State
int _selectedIndex = 0;
static const List
Text('Home Page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
Text('Search Page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
Text('Profile Page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('BottomNavigationBar Example')),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
),
);
}
}
? ?
Drawer
Drawer 是抽屜導航,一般從屏幕左側滑入,包含導航菜單項。
屬性解析
const Drawer({
super.key,
this.backgroundColor, // 抽屜的背景顏色
this.elevation, // 陰影高度
this.shadowColor, // 陰影顏色
this.surfaceTintColor, // 表面顏色
this.shape, // 形狀
this.width, // 寬度
this.child, // 子控件
this.semanticLabel, // 語義標簽
this.clipBehavior, // 剪切行為
});
key:用于標識控件的唯一值。backgroundColor:可選參數(shù),類型為 Color?,表示抽屜的背景顏色。elevation:可選參數(shù),類型為 double?,表示陰影高度。shadowColor:可選參數(shù),類型為 Color?,表示陰影顏色。surfaceTintColor:可選參數(shù),類型為 Color?,表示表面顏色。shape:可選參數(shù),類型為 ShapeBorder?,表示形狀。width:可選參數(shù),類型為 double?,表示寬度。child:可選參數(shù),類型為 Widget?,表示子控件。semanticLabel:可選參數(shù),類型為 String?,表示語義標簽。clipBehavior:可選參數(shù),類型為 Clip?,表示剪切行為。
示例
class ExamplePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Drawer Example'),
),
body: Center(
child: Text(
'Swipe from the left or click on the menu icon to open the drawer.'),
),
drawer: Drawer(
backgroundColor: Colors.white,
elevation: 16.0,
child: ListView(
padding: EdgeInsets.zero,
children:
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
// Handle the tap event here
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () {
// Handle the tap event here
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.contacts),
title: Text('Contacts'),
onTap: () {
// Handle the tap event here
Navigator.pop(context);
},
),
],
),
),
),
);
}
}
? ?
示例
class FirstPage extends StatefulWidget {
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children:
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
onTap: () {
// Handle navigation
},
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
onTap: () {
// Handle navigation
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () {
// Handle navigation
},
),
],
),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
SecondPage(data: 'Hello from First Page')),
);
},
child: Text('Go to Second Page'),
),
),
bottomNavigationBar: BottomNavigationBar(
items: const
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
class SecondPage extends StatelessWidget {
final String data;
SecondPage({required this.data});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Second Page")),
body: Center(child: Text(data)),
);
}
}
柚子快報激活碼778899分享:Flutter 初識:導航控件
好文推薦
本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。