Flutter 使用Navigator進行局部跳轉頁面

Flutter 使用Navigator進行局部跳轉頁面

老孟導讀:Navigator組件使用的頻率不是很高,但在一些場景下非常適用,比如局部表單多頁填寫、底部導航一直存在,每個tab各自導航場景。

Navigator 是管理路由的控件,通常情況下直接使用Navigator.of(context)的方法來跳轉頁面,之所以可以直接使用Navigator.of(context)是因為在WidgetsApp中使用了此控件,應用程序的根控件通常是MaterialApp,MaterialApp包含WidgetsApp,所以可以直接使用Navigator的相關屬性。

Navigator用法非常簡單,如下:

<code>Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
switch (settings.name) {
case 'home':
builder = (context) => PageA();
break;
case 'user':
builder = (context) => PageB();
break;
}
return MaterialPageRoute(builder: builder, settings: settings);
},
)/<code>

initialRoute表示初始化路由,onGenerateRoute表示根據RouteSettings生成路由。

那麼在什麼情況下需要使用Navigator?在需要局部頁面跳轉的地方使用Navigator,如下面的場景:

頭條客戶端舉報場景

頭條客戶端每一個新聞下面都有一個“叉號”,點擊彈出相關信息,點擊其中的局部,會在當前小窗戶內跳轉到舉報頁面,效果如下:

Flutter 使用Navigator進行局部跳轉頁面

此場景就是使用Navigator的典型場景,點擊舉報,並不是全屏切換頁面,而是僅僅在當前彈出的頁面進行切換。

首頁代碼如下:

<code>@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 350,
width: 300,
child: Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settins) {
WidgetBuilder builder;
switch (settins.name) {
case '/':
builder = (context) => PageC();
break;
}
return MaterialPageRoute(builder: builder);
},
),
),
);
}/<code>

Navigator的初始化路由為PageC頁面,PageC頁面代碼如下:

<code>class PageC extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Card(
child: Column(
children: <Widget>[
_buildItem(Icons.clear, '不感興趣', '減少這類內容'),

Divider(),
_buildItem(Icons.access_alarm, '舉報', '標題誇張,內容質量差 等',
showArrow: true, onPress: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return PageD();
}));
}),
Divider(),
_buildItem(Icons.perm_identity, '拉黑作者:新華網客戶端', ''),
Divider(),
_buildItem(Icons.account_circle, '屏蔽', '軍事視頻、駕駛員等'),
],
),
),
);
}

_buildItem(IconData iconData, String title, String content,
{bool showArrow = false, Function onPress}) {
return Row(
children: <Widget>[
Icon(iconData),
SizedBox(
width: 20,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: TextStyle(fontSize: 18),
),
Text(
content,
style: TextStyle(
color: Colors.black.withOpacity(.5), fontSize: 14),
)
],
),
),
!showArrow
? Container()
: IconButton(
icon: Icon(Icons.arrow_forward_ios),
iconSize: 16,
onPressed: onPress,

),
],
);
}
}/<code>

PageC頁面跳轉到PageD頁面,PageD頁面代碼如下:

<code>class PageD extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 250,
color: Colors.grey.withOpacity(.5),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop();
},
),
Text('返回'),
SizedBox(
width: 30,
),
Text('舉報'),
],
),
],
),
);
}
}/<code>
Flutter 使用Navigator進行局部跳轉頁面

最終實現了局部跳轉效果,只在中間區域變化,其他區域不變。

Tab內跳轉

還有一個典型到應用場景就Tab內跳轉,效果如下:

Flutter 使用Navigator進行局部跳轉頁面

底部導航一直存在,每個tab都有自己的導航器。

首頁代碼如下:

<code>class TabMain extends StatefulWidget {
@override
State<StatefulWidget> createState() => _TabMainState();
}

class _TabMainState extends State<TabMain> {
int _currentIndex = 0;

@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: <Widget>[
TabNavigator(0),
TabNavigator(1),
TabNavigator(2),
],
),
bottomNavigationBar: BottomNavigationBar(
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
currentIndex: _currentIndex,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(title: Text('首頁'), icon: Icon(Icons.home)),
BottomNavigationBarItem(title: Text('書籍'), icon: Icon(Icons.book)),
BottomNavigationBarItem(
title: Text('我的'), icon: Icon(Icons.perm_identity)),
],
),
);
}
}/<code>

首頁定義了3個tab及切換效果。

定義TabNavigator:

<code>class TabNavigator extends StatelessWidget {
TabNavigator(this.index);

final int index;

@override

Widget build(BuildContext context) {
return Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settins) {
WidgetBuilder builder;
switch (settins.name) {
case '/':
builder = (context) => ListPage(index);
break;
}
return MaterialPageRoute(builder: builder);
},
);
}
}/<code>

列表頁面,此頁面一般為List頁面,點擊其中一個跳轉到相關詳情頁面,這裡為了簡便,只放了一個跳轉按鈕:

<code>class ListPage extends StatelessWidget {
ListPage(this.index);

final int index;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: RaisedButton(
child: Text('$index'),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return DetailPage();
}));
},
),
),
);
}
}/<code>

詳情頁面

<code>class DetailPage extends StatelessWidget {
@override

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('DetailPage'),
),
);
}
}/<code>

雖然Navigator控件不是特別常用,但在一些場景下非常適用。

交流

老孟Flutter博客地址(近200個控件用法):http://laomengit.com

歡迎加入Flutter交流群(laomengit)


分享到:


相關文章: