Flutter制作自己的第一个全平台APP学习之Navigation篇

已收录   阅读次数: 905
2021-06-2422:01:03 发表评论
摘要

这一篇文章主要是学习Navigation,就是页面中的各种导航,页面的切换之类的,这个在设计App中也很常见,可以极大扩充App的页面广度和深度,让用户更长时间驻留在App上,导航发挥了重要的作用,所以不可不学也,本篇介绍几种常见的导航形式,其实前一篇文章AppBar中也有一部分,主要是底部导航,也算是导航一种啦,有兴趣可以看一看,咱们开始吧……

分享至:
Flutter制作自己的第一个全平台APP学习之Navigation篇

开篇寄语

这一篇文章主要是学习Navigation,就是页面中的各种导航,页面的切换之类的,这个在设计App中也很常见,可以极大扩充App的页面广度和深度,让用户更长时间驻留在App上,导航发挥了重要的作用,所以不可不学也,本篇介绍几种常见的导航形式,其实前一篇文章AppBar中也有一部分,主要是底部导航,也算是导航一种啦,有兴趣可以看一看,咱们开始吧。

前情提要

内容详情

以下内容大多是更改lib下的main.dart文件内容,删掉里面的内容,复制粘贴代码,开启调试就可以出现了。

Tabs

  • 上方出现的菜单栏,可以进行选择,类似于之前学过的底部菜单栏,可以进行选择,试举一例:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TabBarDemo(),
    );
  }
}

class TabBarDemo extends StatefulWidget {
  @override
  _TabBarDemoState createState() => _TabBarDemoState();
}

class _TabBarDemoState extends State<TabBarDemo>
    with SingleTickerProviderStateMixin {
  late TabController _controller;
  int _selectedIndex = 0;

  List<Widget> list = [
    Tab(icon: Icon(Icons.card_travel)),
    Tab(icon: Icon(Icons.add_shopping_cart)),
  ];

  @override
  void initState() {
    super.initState();
    // Create TabController for getting the index of current tab
    _controller = TabController(length: list.length, vsync: this);

    _controller.addListener(() {
      setState(() {
        _selectedIndex = _controller.index;
      });
      print("Selected Index: " + _controller.index.toString());
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            onTap: (index) {
              // Should not used it as it only called when tab options are clicked,
              // not when user swapped
            },
            controller: _controller,
            tabs: list,
          ),
          title: Text('Tabs Demo'),
        ),
        body: TabBarView(
          controller: _controller,
          children: [
            Center(
                child: Text(
              _selectedIndex.toString(),
              style: TextStyle(fontSize: 40),
            )),
            Center(
                child: Text(
              _selectedIndex.toString(),
              style: TextStyle(fontSize: 40),
            )),
          ],
        ),
      ),
    );
  }
}

生成的效果如下图所示:

Flutter制作自己的第一个全平台APP学习之Navigation篇

Routes

  • 分页跳转,点击首页跳转到第二页,点击第二页跳转到第三页,在构建App中是一种很实用的方法,试举例如下:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: TextButton(
          child: Text('View Details'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) {
                return DetailScreen();
              }),
            );
          },
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: TextButton(
          child: Text('Pop!'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

生成效果如下图所示:

除了使用Navigator,还可以使用routes,试举例如下:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/': (context) => HomeScreen(),
        '/details': (context) => DetailScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: TextButton(
          child: Text('View Details'),
          onPressed: () {
            Navigator.pushNamed(
              context,
              '/details',
            );
          },
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: TextButton(
          child: Text('Pop!'),
          onPressed: () {
            Navigator.pop(context);//也可换成这样Navigator.popUntil(context, ModalRoute.withName('/'));
          },
        ),
      ),
    );
  }
}

生成的效果与之前的一致。

Drawer

  • 左侧弹出菜单,点击左上角从左侧弹出一个占据多半屏的栏,也是一种菜单形式,试举例如下:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/': (context) => HomeScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Drawer Demo'),
      ),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: const <Widget>[
            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'),
            ),
            ListTile(
              leading: Icon(Icons.account_circle),
              title: Text('Profile'),
            ),
            ListTile(
              leading: Icon(Icons.settings),
              title: Text('Settings'),
            ),
          ],
        ),
      ),
    );
  }
}

生成效果如下图所示:

Flutter制作自己的第一个全平台APP学习之Navigation篇

有左侧的,自然就有右侧的,试举例如下:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        endDrawer: Drawer(
          child: Container(
            alignment: Alignment.center,
            child: Text('Hello!'),
          ),
        ),
        appBar: AppBar(
          title: Text('Flutter Demo'),
        ),
        body: SafeArea(
          child: Center(),
        ));
  }
}

生成效果如下图所示:

Flutter制作自己的第一个全平台APP学习之Navigation篇

分页滑动

  • TabBar的变型,可以选取不同的页面,试举例如下:
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyScreen(),
    );
  }
}

class MyScreen extends StatelessWidget {
  static const kIcons = <Icon>[
    Icon(Icons.event),
    Icon(Icons.home),
    Icon(Icons.android),
    Icon(Icons.alarm),
    Icon(Icons.face),
    Icon(Icons.language),
  ];
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: kIcons.length,
        // Use a Builder here, otherwise `DefaultTabController.of(context)` below
        // returns null.
        child: Builder(
          builder: (BuildContext context) => Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              children: <Widget>[
                const TabPageSelector(),
                Expanded(
                  child: IconTheme(
                    data: IconThemeData(
                      size: 128.0,
                      color: Theme.of(context).colorScheme.secondary,
                    ),
                    child: const TabBarView(children: kIcons),
                  ),
                ),
                ElevatedButton(
                  onPressed: () {
                    final TabController? controller =
                        DefaultTabController.of(context);
                    if (!controller!.indexIsChanging) {
                      controller.animateTo(kIcons.length - 1);
                    }
                  },
                  child: const Text('SKIP'),
                )
              ],
            ),
          ),
        ));
  }
}

生成效果如下图所示:

Flutter制作自己的第一个全平台APP学习之Navigation篇

NavigationRail

  • 这个是另外一种导航菜单,可以延伸展开,有比较强的灵活度,试举一例:
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key? key}) : super(key: key);

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  var selectedIndex = 0;
  var isRailExtended = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Navigation rail"),
      ),
      body: Row(
        children: <Widget>[
          NavigationRail(
            selectedIndex: selectedIndex,
            onDestinationSelected: (index) {
              setState(() {
                selectedIndex = index;
              });
            },
            extended: isRailExtended,
            elevation: 10,
            leading: Text("You can add\n widget on leading"),
            destinations: [
              NavigationRailDestination(
                  icon: Icon(Icons.ac_unit), label: Text("Ice flake")),
              NavigationRailDestination(
                  icon: Icon(Icons.access_time), label: Text("Main time")),
              NavigationRailDestination(
                  icon: Icon(Icons.mic), label: Text("Start record")),
              NavigationRailDestination(
                  icon: Icon(Icons.business_center),
                  label: Text("My Bussiness")),
              NavigationRailDestination(
                  icon: Icon(Icons.photo_camera), label: Text("View camera")),
              NavigationRailDestination(
                  icon: Icon(Icons.book), label: Text("Some audiobook")),
            ],
            trailing: OutlinedButton(
              child: Text("Toggle rail"),
              onPressed: () {
                setState(() {
                  isRailExtended = !isRailExtended;
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}

生成效果如下图所示:

  • 我的微信
  • 微信扫一扫加好友
  • weinxin
  • 我的微信公众号
  • 扫描关注公众号
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: