开启Fluter基础之旅<二>-------Future再论、常用组件、Material Design风格组件学习

Future再论:

这里在继续往下学习之前,先来看一下Dart语言关于Event-Queue和Microtask Queue需要注意的一个小点,这个在之前https://www.cnblogs.com/webor2006/p/11994645.html已经学习过了,先来回顾一下当时的代码:

import 'dart:async';

void main() {
  testScheduleMicrotask();
}

void testScheduleMicrotask() {
  scheduleMicrotask(() => print('s1'));

  new Future.delayed(new Duration(seconds: 1), () => print('s2'));

  new Future(() => print('s3')).then((_) {
    print('s4');
    scheduleMicrotask(() => print('s5'));
  }).then((_) => print('s6'));

  new Future(() => print('s7'));

  scheduleMicrotask(() => print('s8'));

  print('s9');
}

输出结果为:

 

好,接下来再来改一下:

那又输出啥呢?这里先看结果:

其中相比上面的输出,就是这块不同:

那咱们就针对性的分析加入的这代码的逻辑:

正常来理解应该是s10、s11、s12、s7嘛,为啥输出的跟预想的不一样的,其实是这样的:

所以此时就只会输出s10了,而接下来则会执行下面的这个Future了:

接下来则这块相继会得到执行:

 

所以结果就是s10、s7、s11、s12了。

好,继续再来改,彻底要理解透这块的东东:

其实很好理解,这句会导致之后的then都不会打印,所以是先打印s3,然后再打印下面的s10,最终如下:

记住一点,then中如果是一个Future则不会立马执行了就成。

常用组件:

继续来学Flutter的常用组件,组件太多,挑常用的先学着,这块得要通过项目来实战才行,但是不了解基础用法也不行。

文本组件:

Text:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Text示例"),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              Text(
                  'tttttttttttttttttttttttttttkkkkkkkkkkkkkkkkssssssssssssstestlkdkdkkd'),
            ],
          ),
        ),
      ),
    );
  }
}

咱们可以将它居中显示:

TextOverflow:单行处理

如果只想显示单行,则有几种形式显示:

而还可以省略显示:

它则是底部有一层阴影效果:

TextStyle:

设置删除线:

其中这个删除线的样式也能改呢?

RichText:

其实在Andorid中也有类似的东东,就是在一断文本中可以增加一些点击事件之类的,下面来看一下如何弄:

接下来处理一下点击事件,这里点击之后打开一个网页,先来添加一个依赖包:

这里肯定需要用到异步处理了,如下:

运行看一下效果:

其中这是啥语法呢?

图标及按钮组件:

图标组件Icon展示图标的组件,该组件不可交互,要实现交互图标,可以考虑使用IconButton组件。图标相关组件有以下几个:

  • Icons:框架自带Icon集合
    这个在之前也已经多次用过了:

  • IconButton:可交互的Icon,图标按钮组件IconButton是基于Meterial Design风格的组件,可以响应按下的事件,并且按下时带水波纹效果。如果它的onPressed回调函数为null,那么这个按钮处于禁用状态,并且不可按下。

    其中点击时用了一个三方的toast库,所以需要添加一下依赖:

    效果:
     

  • RaisedButton:是Material Design中的button,一个凸起的材质矩形按钮,它可以响应按下事件,并且按下时会带一个触摸效果。


列表控件:

列表是最常见的需求。在Flutter中,用ListView来显示列表项,支持垂直和水平方向展示,通过一个属性我们就可以控制其方向,列表有以下几类。

基础列表组件:

基础列表组件为ListView组件。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("listview示例"),
        ),
        body: ListView(
          children: <Widget>[
            ListTile(
              leading: Icon(Icons.favorite_border),
              title: Text('favarite_border'),
            ),
            ListTile(
              leading: Icon(Icons.favorite_border),
              title: Text('favarite_border'),
            ),
            ListTile(
              leading: Icon(Icons.favorite_border),
              title: Text('favarite_border'),
            ),
            ListTile(
              leading: Icon(Icons.favorite_border),
              title: Text('favarite_border'),
            ),
          ],
        ),
      ),
    );
  }
}

就不过多解释了,根据效果就能知道上面写的代码的含义,下面再来扩展一下:

可以还差分隔线,可以修改如下:

这里介绍一个小技巧,可以通过IDE来抽象出一个Widget来,如下:

水平列表组件:

水平列表组件即为水平方向排列的组件,列表内部元素以水平方向排列。把ListView组件的scrollDirection属性设置为Axis.horizontal即可。 

注意一下这种是一次性加载100条,而非按需加载,为啥要提这个,因为之后还有一种创建方式。这里又把它抽取一下:

长列表组件【最常用】:

当列表的数据项非常多时,需要使用长列表,比如淘宝后台订单列表、手机通讯录等,这些列表项数据很多。长列表也是使用ListView作为基础组件,只不过需要添加一个列表项构造器itemBuilder。 

很明显就是按需来加载的,也就是有别于上面使用的List.generate()生成的列表,这里给列表中增加一个下划线:

 

网络布局组件:

网格布局组件GridView可以实现多行多列布局的应用场景。使用GridView创建网格列表有多种方式:

  • GridView.count:通过单行展示个数创建。

    先运行看一下:

    可以看到总共是2行,然后是横向滑动的。其中childAspectRatio它是啥意思呢?在网上找了一下:

    其实就是每个隔子高度与宽度的比例,如目前我们设置的是2/3,则高度占2,宽度占3,所以是一个长方形,这里为了看到效果,设置为3行:

    如果设置成3/3,那很显然就成一个正方形了:



    而如果设置成1/3,很显然是更加长了:


    接着我们还可以设置成垂直滚动的:


    而此时的childAspectRatio设置的则是子元素宽和高的比例,跟那个横向滑动是相反的。

  • GridView.builder():
    跟ListView一样,也可以用Builder来进行构建:

      

表单组件:

表单是一个包含表单元素的区域。表单元素允许用户输入内容,比如文本域,下拉列表,单选框,复选框等。常见应用场景有:登录、注册、输入信息等。表单里有两个重要的组件,一个是Form组件,用来左整个表单提交使用的;另一个是TextFormField组件,用来做用户输入的。 

Form组件常用属性:

说到表单,当然最典型的就是用户登录了,所以下面来编写一个用户登录的表单界面,这里直接贴出代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("gridview示例"),
          ),
//          body: new GridViewWidget()),
          body: LoginPage()),
    );
  }
}

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  String _userName;
  String _password;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Column(
        children: <Widget>[
          Container(
            padding: const EdgeInsets.all(10.0), //间隙
            child: Form(
              child: Column(
                children: <Widget>[
                  TextFormField(
                    decoration: InputDecoration(labelText: '请输入用户名'),
                    onSaved: (value) {
                      print('$value');
                      _userName = value;
                    },
                    onFieldSubmitted: (value) {
                      print('onFieldSubmitted : $value');
                    },
                  ),
                  TextFormField(
                    decoration: InputDecoration(labelText: '请输入密码'),
                    onSaved: (value) {
                      print('$value');
                      _password = value;
                    },
                    validator: (value) {
                      //这里做个校验,如果不足6位给出错误提示
                      return value.length < 6 ? "密码长度不够6位" : null;
                    },
                  ),
                  Container(
                    margin: const EdgeInsets.only(top: 20.0),
                    width: 400.0,
                    height: 40.0,
                    child: RaisedButton(
                      child: Text('登录'),
                      onPressed: () {
                        //TODO 进行登录
                      },
                    ),
                  )
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}

运行一下:

此时则需要来处理点击事件了,这里面有个写法比较陌生,先记住,之后还会再学的:

运行看一下效果:

此时日志输出如下:

另外,密码框现在还是明文的,得搞成密文风格:

Material Design风格组件:

Material Design是由谷歌推出的全新设计语言,这种设计语言旨在为手机、平板电脑、台式机和其他平台提供更一致、更广泛的外观和感觉。Material Design风格是一直非常有质感的设计风格,并会提供一些默认的交互动画,对于搞Android开发的来说应该耳熟能详了。

App结构和导航组件:

MaterialApp(应用组件):

MaterialApp代表使用Material Design风格的应用,里面包含了其他所需的基本控件。官方提供的示例demo就是从MaterialApp这个主组件开始的,我们在之前也已经使用多次了,这里再来从头梳理一下它:

设置主页:

使用home属性设置应用的主页,即整个应用的主组件。

路由处理:

routes对象是一个Map<String, WidgetBuilder>。当使用Navigator.pushNamed来跳转路由的时候,通过routes查找路由名字,然后使用对应的WidgetBuilder来构造一个带有页面切换动画的MaterialPageRoute。如果应用只有一个界面,则不用设置整个属性,使用home即可。

下面来使用一下:

import 'package:flutter/material.dart';

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

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

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MaterialApp示例'),
      ),
      body: Center(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, '/other');
        },
        tooltip: '路由跳转',
        foregroundColor: Color(0xffffffff),
        backgroundColor: Color(0xff000000),
        //阴影
        elevation: 0.0,
        child: Icon(Icons.arrow_forward),
      ),
    );
  }
}

class OtherPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OtherPage'),
      ),
    );
  }
}

此时运行就可以实现页面的跳转了:

这里使用了FloatingActionButton,顺便再来学一下它的其它用法,还可以控制它的位置:

 还可以将圆形变为方形:

 

自定义主题:

应用程序的主题,各种定制的颜色都可以设置,用于程序主题切换。 这个在未来用到时再进一步学习。

Scaffold(脚手架组件):

Scaffold实现了基本的Material Design布局。只要是在Material Design中定义过的单个界面显示的布局组件元素,都可以使用Scaffold来绘制。

AppBar(应用按钮组件):

应用按钮组件有AppBar和SliverAppBar。它们是Material Design中的AppBar,也就是Android中的ToolBar。
AppBar和SliverAppBar都继承自StatefulWidget,两者的区别在于AppBar的位置是固定在应用最上面的;而SliverAppBar是可以跟随内容滚动的。

BottomNavigatorBar(底部导航栏):

这个就是典型的像微信那种底部的菜单TAB效果,下面来实现一下:

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

class _HomePageState extends State<HomePage> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MaterialApp示例'),
      ),
      body: Center(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, '/other');
        },
        tooltip: '路由跳转',
        foregroundColor: Color(0xffffffff),
        backgroundColor: Color(0xff000000),
        //阴影
        elevation: 0.0,
        child: Icon(Icons.arrow_forward),
//        shape: RoundedRectangleBorder(),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.message),
            title: Text('信息'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.contacts),
            title: Text('通讯录'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.near_me),
            title: Text('发现'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.account_circle),
            title: Text('我'),
          ),
        ],
        currentIndex: _currentIndex,
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

运行看一下:

再运行:

哇塞,效果还蛮好的呢?下面点击完之后,咱们在上面切换一下内容,这里简单切换一下文件模拟下:

再运行一下:

关于Material Design风格组件还有很多,下次再继续。

posted on 2020-03-22 14:02  cexo  阅读(561)  评论(0编辑  收藏  举报

导航