继续我们的flutter之旅,今天学首页怎么写,APP的首页目前比较单一,都是下面几个菜单,上面几个菜单,或者侧面一个我的,所以可以写一个活的套用,以后就不用麻烦了。

    前言:样式自定义基本上都是一样的,什么圆角,什么阴影,什么旋转,什么渐变,总结一下以后别忘了。

    样式1:

import 'package:flutter/material.dart';void main() => runApp(new MyApp());//Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.//Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    // TODO: implement build    return new MaterialApp(      title: "样式布局",      home: new Scaffold(        appBar: new AppBar(          title: new Text("样式布局"),        ),        body: new Center(          child: new FormTestRoute1(),        ),      ),    );  }}class FormTestRoute1 extends StatefulWidget {  @override  _FormTestRouteState1 createState() => new _FormTestRouteState1();}class _FormTestRouteState1 extends State
 {  @override  Widget build(BuildContext context) {    return Padding(      //上下左右各添加16像素补白      padding: EdgeInsets.all(16.0),      child: Column(        //显式指定对齐方式为左对齐,排除对齐干扰        crossAxisAlignment: CrossAxisAlignment.start,        children: 
[          Padding(            //左边添加8像素补白            padding: const EdgeInsets.only(left: 8.0),            child: Text("hi yun1"),          ),          Padding(            //上下各添加8像素补白            padding: const EdgeInsets.symmetric(vertical: 8.0),            child: Text("hi yun2"),          ),          Padding(            // 分别指定四个方向的补白            padding: const EdgeInsets.fromLTRB(20.0, .0, 20.0, 20.0),            child: Text("hi yun3"),          ),          DecoratedBox(              decoration: BoxDecoration(                  gradient: LinearGradient(                      colors: [Colors.red, Colors.orange[700]]), //背景渐变                  borderRadius: BorderRadius.circular(3.0), //3像素圆角                  boxShadow: [                    //阴影                    BoxShadow(                        color: Colors.black54,                        offset: Offset(2.0, 2.0),                        blurRadius: 4.0)                  ]),              child: Padding(                padding: EdgeInsets.symmetric(horizontal: 80.0, vertical: 18.0),                child: Text(                  "Login",                  style: TextStyle(color: Colors.white),                ),              )),        ],      ),    );  }}

    blob.png

    

    样式2:

import 'package:flutter/material.dart';void main() => runApp(new MyApp());//Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.//Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    // TODO: implement build    return new MaterialApp(      title: "样式布局",      home: new Scaffold(        appBar: new AppBar(          title: new Text("样式布局"),        ),        body: new Center(          child: new FormTestRoute1(),        ),      ),    );  }}class FormTestRoute1 extends StatefulWidget {  @override  _FormTestRouteState1 createState() => new _FormTestRouteState1();}class _FormTestRouteState1 extends State
 {  @override  Widget build(BuildContext context) {    return Padding(      //上下左右各添加16像素补白      padding: EdgeInsets.all(16.0),      child: Column(        //显式指定对齐方式为左对齐,排除对齐干扰        crossAxisAlignment: CrossAxisAlignment.start,        children: 
[          Container(            margin: EdgeInsets.only(                top: 50.0, left: 120.0, right: 0.0, bottom: 50.0),            //容器外补白            constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0),            //卡片大小            decoration: BoxDecoration(                //背景装饰                gradient: RadialGradient(                    //背景径向渐变                    colors: [Colors.red, Colors.orange],                    center: Alignment.topLeft,                    radius: .98),                boxShadow: [                  //卡片阴影                  BoxShadow(                      color: Colors.black54,                      offset: Offset(2.0, 2.0),                      blurRadius: 4.0)                ]),            transform: Matrix4.rotationZ(.2),            //卡片倾斜变换            alignment: Alignment.center,            //卡片内文字居中            child: Text(              //卡片文字              "5.20", style: TextStyle(color: Colors.white, fontSize: 40.0),            ),          ),          Container(            margin: EdgeInsets.all(20.0), //容器外补白            color: Colors.orange,            child: Text("hi yun~"),          ),          Container(            padding: EdgeInsets.all(20.0), //容器内补白            color: Colors.orange,            child: Text("hi yun~"),          ),        ],      ),    );  }}

    blob.png

    Scaffold:

    大多数路由页都会包含一个导航栏,有些路由页可能会有抽屉菜单(Drawer)以及底部Tab导航菜单等。如果每个页面都需要开发者自己手动去实现,这会是一件非常无聊的事。幸运的是,我们前面提到过,Flutter Material库提供了一个Scaffold Widget,它是一个路由页的骨架,可以非常容易的拼装出一个完整的页面。

import 'package:flutter/material.dart';void main() => runApp(new MyApp());//Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.//Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    // TODO: implement build    return new MaterialApp(      title: "Scaffold首页",      home: new Scaffold(//        appBar: new AppBar(//          title: new Text("Scaffold首页"),//        ),        body: new Center(          child: new FormTestRoute1(),        ),      ),    );  }}class FormTestRoute1 extends StatefulWidget {  @override  _FormTestRouteState1 createState() => new _FormTestRouteState1();}class _FormTestRouteState1 extends State
    with SingleTickerProviderStateMixin {  int _selectedIndex = 1;  void _onItemTapped(int index) {    setState(() {      _selectedIndex = index;    });  }  void _onAdd() {}  TabController _tabController;  List tabs = ["Yun1", "Yun2", "Yun3"];  @override  void initState() {    // TODO: implement initState    super.initState();    _tabController = TabController(length: tabs.length, vsync: this);  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: new Text("Scafford首页"),        leading: Builder(builder: (context) {          return IconButton(            icon: Icon(Icons.dashboard, color: Colors.white), //自定义图标            onPressed: () {              // 打开抽屉菜单              Scaffold.of(context).openDrawer();            },          );        }),        actions: 
[          IconButton(            icon: Icon(              Icons.share,            ),            onPressed: () {},          ),        ],        bottom: TabBar(          controller: _tabController,          tabs: tabs.map((e) => Tab(text: e)).toList(),        ),      ),      drawer: new MyDrawer(),      body: TabBarView(        controller: _tabController,        children: tabs.map((e) {          return Container(            alignment: Alignment.center,            child: Text(              e,              textScaleFactor: 5,            ),          );        }).toList(),      ),//      bottomNavigationBar: BottomNavigationBar(//        items: 
[//          BottomNavigationBarItem(//              icon: Icon(Icons.home), title: new Text("Yun1")),//          BottomNavigationBarItem(//              icon: Icon(Icons.business), title: new Text("Yun2")),//          BottomNavigationBarItem(//              icon: Icon(Icons.school), title: new Text("Yun3")),//        ],//        currentIndex: _selectedIndex,//        fixedColor: Colors.blueGrey,//        onTap: _onItemTapped,//      ),      bottomNavigationBar: BottomAppBar(        color: Colors.white,        shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞        child: Row(          children: [            IconButton(icon: Icon(Icons.home)),            SizedBox(), //中间位置空出            IconButton(icon: Icon(Icons.business)),          ],          mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间        ),      ),      floatingActionButton: FloatingActionButton(        child: Icon(Icons.add),        onPressed: _onAdd,      ),      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,    );  }}// 抽屉class MyDrawer extends StatelessWidget {  const MyDrawer({    Key key,  }) : super(key: key);  @override  Widget build(BuildContext context) {    return Drawer(      child: MediaQuery.removePadding(        context: context,        // DrawerHeader consumes top MediaQuery padding.        removeTop: true,        child: Column(          crossAxisAlignment: CrossAxisAlignment.start,          children: 
[            Padding(              padding: const EdgeInsets.only(top: 38.0),              child: Row(                children: 
[                  Padding(                    padding: const EdgeInsets.symmetric(horizontal: 16.0),                    child: ClipOval(                      child: Image.asset(                        "imgs/avatar.png",                        width: 80,                      ),                    ),                  ),                  Text(                    "Wendux",                    style: TextStyle(fontWeight: FontWeight.bold),                  )                ],              ),            ),            Expanded(              child: ListView(                children: 
[                  ListTile(                    leading: const Icon(Icons.add),                    title: const Text('Add account'),                  ),                  ListTile(                    leading: const Icon(Icons.settings),                    title: const Text('Manage accounts'),                  ),                ],              ),            ),          ],        ),      ),    );  }}

    blob.png blob.png blob.png

    总结:这块的关键leading,TabBar,TabBarView,BottomNavigationBar,BottomAppBar的使用,写法都是固定的,需要相互配合,多练吧~

    60d2c107ly1g2ii746jyzg208c05kn3j.gif