Flutter之旅(一)-Flutter项目架构、HelloWord及ListView

AppBar

pubspec.yaml文件的dependencies节点下增加fluttertoast库以用来演示运用

# dependencies节点下主要引用第三方库
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  fluttertoast: ^8.2.1

左侧增加按钮交互

appBar增加左侧菜单按钮的action是经过leading小部件,并经过IconButton增加按钮图标和点击onPressed办法,如下:

class ViewStructure extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[300],
      appBar: AppBar(
        leading: IconButton( //经过leading小部件增加菜单按钮
          icon: const Icon(Icons.menu),
          tooltip: 'menu', //润饰阐明
          onPressed: () => Fluttertoast.showToast(msg: "menu"),
        ),
        title: const Text('Flutter界面结构'),
        elevation: 0.0, // 去除appbar下的暗影
      ),
      body: null,
    );
  }
}

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

appBar右侧增加按钮交互

appBar右侧增加交互咱们能够经过actions来完成,在title特点下面增加如下:

class ViewStructure extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[300],
      appBar: AppBar(
        leading: IconButton( //经过leading小部件增加菜单按钮
          icon: const Icon(Icons.menu),
          tooltip: 'menu', //润饰阐明
          onPressed: () => Fluttertoast.showToast(msg: "menu"),
        ),
        title: const Text('Material风格界面结构'),
        actions: <Widget>[ //右边经过actions设置一系列动作
          IconButton(
            icon: const Icon(Icons.search),
            tooltip: 'Search',
            onPressed: () => Fluttertoast.showToast(msg: "search"),
          )
        ],
        elevation: 0.0, // 去除appbar下的暗影
      ),
      body: null,
    );
  }
}

actions特点中能够继续增加IconButton增加多个交互事件:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

TabBar、TabView及TabController

TabBar便是Tab(选项卡或标签)组成的导航栏,假如熟悉Android开发的同学能够理解它便是对应着Android开发中的TabLayout,在Flutter中要达到标签导航切换的功能需求TabbarTabViewTabController系一起来完成。

TabController

咱们基于上一小节的代码增加一个tab标签挑选切换对应ui的功能,首先需求增加TabController,这儿运用框架自带的DefaultTabController,并经过length特点设置为3个tab,如下:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar
这儿能够见到Scaffold小部件被DefaultTabController包裹。

TabBar

appBar中的经过bottom特点在title下增加TabBar小部件,TabBar中能够经过tabs设置标签的内容,并对标签的作用,如选中色彩或指示器进行调整:

bottom: const TabBar(
  //TabBar
  unselectedLabelColor: Colors.black38,
  //未被挑选的标签的色彩
  indicatorColor: Colors.yellow,
  //标签挑选指示器色彩
  indicatorSize: TabBarIndicatorSize.label,
  //设置指示器长度和tab长度相同
  indicatorWeight: 2.0,
  //指示器的高度
  tabs: <Widget>[
    //设置每个tab的icon或文本
    Tab(icon: Icon(Icons.car_crash)),
    Tab(icon: Icon(Icons.cabin)),
    Tab(icon: Icon(Icons.flag)),
  ],
),

TabView

TabView便是设置标签选项对应的视图内容,相似Android开发中TabLayout切换选中的Fragment,那么TabBarView设置的多个对应Widget相当于一个个Fragment,咱们在视图的body中显示,如下:

body: const TabBarView(
  //标签对应的视图
  children: <Widget>[
    //每个标签对应view的内容
    Icon(Icons.car_crash, size: 136.0, color: Colors.lightBlue),
    Icon(Icons.cabin, size: 136.0, color: Colors.yellow),
    Icon(Icons.flag, size: 136.0, color: Colors.red),
  ],
),

全体作用如下:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

Drawer

Android开发中也有Material风格的DrawerLayout,它便是一个侧边栏抽屉的作用,主要是用于侧边栏菜单等,而flutterdrawer作用和DrawerLayout是相同的,咱们能够在body下增加一个drawer的特点(假如是endDrawer就代表是在右边显示),然后运用Container小部件增加抽屉侧边栏(drawer)的背景色及增加一个文本,代码如下:

drawer: Container(
  color: Colors.lightBlue,
  padding: const EdgeInsets.all(16.0), //设置Container小部件全体的内边距
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    //设置主轴对齐,能够理解为Column部件中的wiget都全体居中
    children: const <Widget>[
      Text(
        'drawer显示',
        style: TextStyle(color: Colors.white),
      )
    ],
  ),
),

作用如下:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

运用Drawer部件完成抽屉侧边栏

咱们把上面的Container小部件换成Drawer,子Widget运用一个ListView来处理:

drawer: Drawer(
  child: ListView(
    padding: EdgeInsets.zero,
    children: <Widget>[],
    ),
 )

<Widget>[]中首先增加一个UserAccountsDrawerHeader增加一个用户信息的View,并设置背景图:

UserAccountsDrawerHeader(
  accountName: const Text('柒叁'),
  accountEmail: const Text('123455678@gmail.com'),
  currentAccountPicture: const CircleAvatar(
    backgroundImage: NetworkImage(
        'https://p3-passport.byteimg.com/img/user-avatar/aede74f1a2d5008f871a8c1b95b2a3ce~180x180.awebp'),
  ),
  decoration: BoxDecoration( //设置UserAccountsDrawerHeader的背景图片
      color: Colors.yellow[200],
      image: DecorationImage(
          fit: BoxFit.cover, //填充溢整个区域
          colorFilter: ColorFilter.mode(Colors.lightBlue.withOpacity(0.6),
              BlendMode.srcOver),  //色彩的滤镜
          image: const NetworkImage(
              'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/04d31e46137f4981b7aaa6f6c83f1cc1~tplv-k3u1fbpfcp-watermark.image?'))),
),

假如需求方便自定义一点能够直接运用DrawerHeader,如下:

DrawerHeader(
  decoration: BoxDecoration(
    //设置header的背景色
    color: Colors.grey[200],
  ),
  child: Column(
    children: <Widget>[
      // const Icon(Icons.people,color: Colors.lightBlue,size: 48),
      ClipOval( //设置圆形切开
        child: Image.network(
          'https://p3-passport.byteimg.com/img/user-avatar/aede74f1a2d5008f871a8c1b95b2a3ce~180x180.awebp',
          width: 80,
          height: 80,
          fit: BoxFit.cover,
        ),
      ),
      const Text('柒叁'),
    ],
  ),
),

UserAccountsDrawerHeader之下经过ListTitle增加三个item,如下:

ListTile(
  title: const Text('Rate us', textAlign: TextAlign.start),
  leading:
      const Icon(Icons.star, color: Colors.lightBlue, size: 32),
  onTap: () => Navigator.pop(context), //点击item关闭抽屉
  // trailing: , 在标题右边增加图片trailing
),
ListTile(
  title: const Text('Share', textAlign: TextAlign.start),
  leading: const Icon(Icons.share,
      color: Colors.lightBlue, size: 32),
  onTap: () => Navigator.pop(context),
  // trailing: ,
),
ListTile(
  title: const Text('Setting', textAlign: TextAlign.start),
  leading: const Icon(Icons.settings,
      color: Colors.lightBlue, size: 32),
  onTap: () => Navigator.pop(context),
  // trailing: ,
),

当咱们运用运用Drawer时会主动增加左面的菜单按钮的,并主动点击翻开抽屉,咱们先把AppBar中设置的leading给注释掉,呈现如下作用:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

BottomNavigationBar

bottomNavigationBar顾名思义便是底部的导航栏,经过BottomNavigationBar小部件的items特点增加一系列的BottomNavigationBarItem得到底部导航栏:

bottomNavigationBar: BottomNavigationBar(
  items: const [
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      label: "首页",
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.shop),
      label: "商城",
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.people),
      label: "个人中心",
    ),
  ],
),

作用如下:

Flutter之旅(二)—Material风格的界面结构:AppBar、TabBar、Drawer及BottomNavigationBar

BottomNavigationBar的还能够设置以下几个特点:

currentIndex: 1,  //设置当前的选中的tab
type: BottomNavigationBarType.fixed,//设置是刚好屏幕内填充
fixedColor: Colors.red,  //设置选中的色彩

一般来说currentIndex这个是动态改变的,所以咱们需求运用变量来设置,也便是处理底部导航栏切换选中的状况,这儿需求运用到setState办法,setState办法需求运用到StatefulWidget,所以咱们需求自定义一个Widget继承StatefulWidget

class BottomNavigationBarDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return BottomNavigationBarDemoState();
  }
}

BottomNavigationBarDemoState继承State

class BottomNavigationBarDemoState extends State<BottomNavigationBarDemo> {
  int _currentIndex = 0;
  //监听状况改变
  void _onTapHandler(int index) {
    setState(() {
      _currentIndex = index;
    });
  }
  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _currentIndex,  //设置当前的选中的tab
      type: BottomNavigationBarType.fixed,//设置是刚好屏幕内填充
      fixedColor: Colors.red,  //设置选中的色彩
      onTap: _onTapHandler,
      // 切换状况的特点
      items: const [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: "首页",
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.shop),
          label: "商城",
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: "个人中心",
        ),
      ],
    );
  }
}

对于底部导航栏切换状况的改变处理需求做以下几点:

  1. 声明变量_currentIndex;
  2. _currentIndex赋值给BottomNavigationBarcurrentIndex特点;
  3. 声明_onTapHandler办法更新变量_currentIndex的值;
  4. BottomNavigationBaronTap特点增加_onTapHandler办法的调用。

本文介绍的示例代码:view_structure.dart