前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter lesson 7: Flutter组件之基础组件(三)

Flutter lesson 7: Flutter组件之基础组件(三)

作者头像
踏浪
发布2019-07-31 11:42:15
1.4K0
发布2019-07-31 11:42:15
举报
文章被收录于专栏:踏浪的文章踏浪的文章

上一节我们介绍了Row, Column, Image, Text四个基础组件,这一节我们来看看下面几个组件。

Icon

Icon就是图标,字体图标,矢量图。在web前端中我们使用图标可以自己定义字体与SVG,使用阿里图标上面的图标。在Flutter中,google则为我们集成了一些常用的图标。

看看Icon的属性有哪些

代码语言:javascript
复制
const Icon(
  this.icon, {
  Key key,
  this.size,
  this.color,
  this.semanticLabel,
  this.textDirection,
}) : super(key: key);

我们能够用到的就是 sizecolor 两个属性,第一个是字体。使用Icons类。下面有很多图标。

代码语言:javascript
复制
child: Column(
  crossAxisAlignment: CrossAxisAlignment.center,
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Icon(
      Icons.speaker,
      color: Colors.red,
      size: 100,
    ),Icon(
      Icons.star_half,
      color: Colors.blue,
      size: 100,
    ),Icon(
      Icons.volume_up,
      color: Colors.red,
      size: 100,
    )
  ],
)

当然,这些都是 Flutter material 中自带的一些图标,如果我们需要自己定义图标怎么弄呢?这也是可以的,就像我们在web中使用 iconfont 一样。

自定义的微信与QQ图标
自定义的微信与QQ图标
代码语言:javascript
复制
Icon(
  MyIcons.weChat,
  color: Colors.green,
  size: 100,
),Icon(
  MyIcons.qq,
  color: Colors.blue,
  size: 100,
)

上面的代码中出现了 MyIcons 这个类。哪里来的呢?其实这个是我们自己创建的类,怎么创建的来看看。

代码语言:javascript
复制
import 'package:flutter/material.dart';

class MyIcons {
  // 微信图标
  static const IconData weChat = const IconData(
    0xe63d,
    fontFamily: "MyIcons",
    matchTextDirection: true
  );

  static const IconData qq = const IconData(
    0xe6ca,
    fontFamily: "MyIcons",
    matchTextDirection: true
  );
}

MyIcons 是我们自己创建的类,里面定义了两个Icon,一个名字是weChat,另一个是qq。使用的是IconData这个类创建,里面有三个参数。Icon的Unicode编码,这个在阿里图标上表示在这里

Unicode
Unicode

我们把上面的 &# 换成 0 就可以了。

fontFamily呢?是我们自己定义的字体

配置字体
配置字体

字体呢就是我们在阿里图标上面下载下来的文件。

这些就是关于 Icon 的简单介绍。

RaisedButton

其实这就是一个按钮,一个凸起的材质矩形的按钮。

代码语言:javascript
复制
const RaisedButton({
  Key key,
  @required VoidCallback onPressed, // 按钮点击事件,必选
  ValueChanged<bool> onHighlightChanged, //水波纹高亮变化回调,按下返回true,抬起返回false 使用默认值就可以
  ButtonTextTheme textTheme, //按钮的主题
  Color textColor, //按钮文字的颜色
  Color disabledTextColor, //按钮禁用时候文字颜色
  Color color, //按钮背景色
  Color disabledColor, //按钮禁用时候背景色
  Color highlightColor, // 点击或者toch控件高亮的时候显示在控件上面,水波纹下面的颜色
  Color splashColor, //水波纹的颜色
  Brightness colorBrightness, //按钮主题高亮
  double elevation, //按钮下面的阴影
  double highlightElevation, //高亮时候的阴影
  double disabledElevation, //禁用时候的阴影
  EdgeInsetsGeometry padding,
  ShapeBorder shape, //设置形状
  Clip clipBehavior = Clip.none,
  MaterialTapTargetSize materialTapTargetSize,
  Duration animationDuration,
  Widget child, // 子元素,一般是文字,如果是icon,有专门的icon图标
})

属性有很多,能用到的也就那么几个,大部分都是使用的默认值。

下面是App中的源码

代码语言:javascript
复制
child: Column(
  children: <Widget>[
    RaisedButton(
      onPressed: () {},
      child: Text("textColor文本的颜色,color背景颜色,highlightColor按钮按下的颜色"),
      textColor: Color(0xffff0000),
      color: Color(0xfff1f1f1),
      highlightColor: Color(0xff00ff00),
    ),
    RaisedButton(
      onPressed: () {},
      child: Text("disabledTextColor禁用时文本颜色,disabledColor禁用时背景颜色"),
      disabledTextColor: Color(0xff999999),
      disabledColor: Color(0xffff0000),
    ),
    RaisedButton(
      onPressed: () {},
      child: Text("splashColor水波的颜色,disabledColor禁用时背景颜色"),
      splashColor: Color(0xffff0000),
    ),
    RaisedButton(
      onPressed: () {},
      child: Text("colorBrightness按钮主题高亮 Brightness.light"),
      colorBrightness: Brightness.light,
    ),
    RaisedButton(
      onPressed: () {},
      child: Text("colorBrightness按钮主题高亮 Brightness.dark"),
      colorBrightness: Brightness.dark,
    ),
    Container(
      margin: EdgeInsets.only(top: 20.0),
      child: RaisedButton(
        onPressed: () {},
        child: Text(
            "elevation按钮下面的阴影,highlightElevation高亮时候的阴影,disabledElevation按下的时候的阴影"),
        elevation: 5.0,
      ),
    ),
    Container(
      margin: EdgeInsets.only(top: 20.0),
      child: RaisedButton(
        onPressed: () {},
        child: Text(
            "elevation按钮下面的阴影,highlightElevation高亮时候的阴影,disabledElevation按下的时候的阴影"),
        highlightElevation: 5,
      ),
    ),
    Container(
      margin: EdgeInsets.only(top: 20.0),
      child: RaisedButton(
        onPressed: () {},
        child: Text(
            "elevation按钮下面的阴影,highlightElevation高亮时候的阴影,disabledElevation按下的时候的阴影"),
        disabledElevation: 5.0,
      ),
    ),
    RaisedButton(
      onPressed: () {},
      child: Text(
          "onHighlightChanged 水波纹高亮变化回调,按下返回true,抬起返回false"),
      onHighlightChanged: (bool b) => Fluttertoast.showToast(
        msg: '$b',
        toastLength: Toast.LENGTH_LONG,
        fontSize: 12
      ),
    ),
    RaisedButton(
      onPressed: () => Fluttertoast.showToast(
        msg: '你点击了按钮',
        toastLength: Toast.LENGTH_LONG,
        fontSize: 12
      ),
      child: Text("onPressed点击事件"),
    ),
  ],
)v

就像上面的代码中看到的,除了onPressed是必选以外,其余的属性基本上用的不是特别的多,有一些没有涉及到的属性,有兴趣可以自己下来了解。

Scaffold

之前简单提到过Scaffold,因为我们用到这个Widget的时候实在是太多了。

代码语言:javascript
复制
const Scaffold({
  Key key,
  this.appBar,
  this.body,
  this.floatingActionButton,
  this.floatingActionButtonLocation,
  this.floatingActionButtonAnimator,
  this.persistentFooterButtons,
  this.drawer,
  this.endDrawer,
  this.bottomNavigationBar,
  this.bottomSheet,
  this.backgroundColor,
  this.resizeToAvoidBottomPadding,
  this.resizeToAvoidBottomInset,
  this.primary = true,
  this.drawerDragStartBehavior = DragStartBehavior.start,
  this.extendBody = false,
})

Scaffold可以说是一个容器,里面可以设置很多地方的Widget,比如AppBardrawerbottomNavigationBar等等。下面的每一部分又有自己单独的设置方法。还是来看看怎么使用。

AppBar

代码语言:javascript
复制
AppBar({
  Key key,
  this.leading,
  this.automaticallyImplyLeading = true,
  this.title,
  this.actions,
  this.flexibleSpace,
  this.bottom,
  this.elevation,
  this.shape,
  this.backgroundColor,
  this.brightness,
  this.iconTheme,
  this.actionsIconTheme,
  this.textTheme,
  this.primary = true,
  this.centerTitle,
  this.titleSpacing = NavigationToolbar.kMiddleSpacing,
  this.toolbarOpacity = 1.0,
  this.bottomOpacity = 1.0,
})

来看看AppBar中每一部分的布局,下面图片来自Flutter官网

AppBar
AppBar

leading

正如上面的图片中看到的,这个属性可以设置AppBar左侧的内容

leading
leading
代码语言:javascript
复制
appBar: AppBar(
  title: Text('AppBar'),
  leading: IconButton(
    onPressed: () => {},
    icon: Icon(
      Icons.nature
    ),
  ),
),

这里设置的是一个 nature 图标,当然,你也可以设置其他的图标,或者是其他的Widget,文字,图片等等。

automaticallyImplyLeading

官方的解释为

Controls whether we should try to imply the leading widget if null

我理解为:如果没有设置leading属性,是否需要将leading默认设置为null。左右可能就是做一个站位。默认是true,使用默认值就行。

title

标题。不用多说。

actions

正如上面的图片中看到的,这个属性可以设置AppBar中右侧的显示。上面图片中显示了三个,说明这是一个Widget List。

actions
actions
代码语言:javascript
复制
actions: <Widget>[Icon(Icons.book), Icon(Icons.satellite),Center(child: Text('action'))]

flexibleSapce

这个最上面的图也有解释。整个AppBar相当于采用flex布局,flexibleSapce空间属于AppBar中除了整个空间。包含了leading,title以及bottom区间。值是一个Widget。

为什么这样说呢?

代码语言:javascript
复制
flexibleSpace: Container(
  color: Colors.green,
  // alignment: Alignment.center,
  child: Text("flexibleSpace")
)

上面的代码中我们把alignment属性注释掉了,结果如下

alignment没有设置或者说是alignment使用了默认值
alignment没有设置或者说是alignment使用了默认值

接着我们取消注释

设置 alignment: Alignment.center 后
设置 alignment: Alignment.center 后

这就是原因。不过这个属性好像不怎么用得着啊。整个AppBar可能用得多的地方就是leading,title和actions了吧。

bottom

一个 AppBarBottomWidget 对象,通常是 TabBar。用来在 Toolbar 标题下面显示一个 Tab 导航栏

代码语言:javascript
复制
bottom: PreferredSize(
  child: Text('bottom区间'),
  preferredSize: Size.fromHeight(100),
),
bottom
bottom

你还可以在bottom中添加TabBar,这样就更加充分利用了bottom这个属性

在AppBar下面设置TabBar
在AppBar下面设置TabBar
代码语言:javascript
复制
import 'package:flutter/material.dart';

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

class ScaffoldInfo extends StatelessWidget {
  ScaffoldInfo({Key key, this.title}) : super(key: key);
  final String title;
  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      bottomNavigationBar: Text('1'),
      body: Container(
        padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
        child: DefaultTabController(
          length: 6,
          child: Scaffold(
            appBar: AppBar(
              title: Text('AppBar'),
              leading: IconButton(
                onPressed: () => {},
                icon: Icon(
                  Icons.nature
                ),
              ),
              automaticallyImplyLeading: true,
              actions: <Widget>[Icon(Icons.book), Icon(Icons.satellite),Center(child: Text('action'))],
              flexibleSpace: Container(
                color: Colors.green,
                alignment: Alignment.center, 
                child: Text("flexibleSpace")
              ),
              bottom: TabBar(
                isScrollable: true,
                tabs: <Widget>[
                  Tab(text: 'Tab 1'),
                  Tab(text: 'Tab 2'),
                  Tab(text: 'Tab 3'),
                  Tab(text: 'Tab 4'),
                  Tab(text: 'Tab 5'),
                  Tab(text: 'Tab 6'),
                ],
              ),
              // elevation: 20,
              backgroundColor: Colors.red,
              brightness: Brightness.dark,
              // centerTitle: true,
            ),
            body: TabBarView(
              children: <Widget>[
                Center(child: Text('Tab 1')),
                Center(child: Text('Tab 2')),
                Center(child: Text('Tab 3')),
                Center(child: Text('Tab 4')),
                Center(child: Text('Tab 5')),
                Center(child: Text('Tab 6')),
              ],
            )
          ),
        )
      )
    );
  }
}

这里收涉及到了TabBar以及TabBarView两个类。这里不多讲,需要注意的是这两个都需要设置一个controller属性,如果不设置,可以使用DefaultTabController创建默认的容器。

elevation

这个属性是设置整个AppBar的阴影的大小,值是一个double

下面是设置了elevation: 20,的前后对比,还是使用默认的就可以了

设置了 elevation: 20
设置了 elevation: 20

backgroundColor

AppBar的背景色。如果flexibleSapce设置了背景色,这个背景色将会被覆盖。

brightness

AppBar的主题,有两个选择,Brightness.dark 或者 Brightness.light

centerTitle

标题是否居中显示,默认值根据不同的操作系统,显示方式不一样。安卓可能在左侧,IOS则是居中。

body

主题内容区域,这个区域就不介绍了,body可以设置各种Widget。

floatingActionButton

这是一个浮动按钮,注意参数就是一个child(一般是一个Icon),其次就是 onPressed 点击事件。其余的可以使用默认属性,或者你修改一下背景色等等。

代码语言:javascript
复制
const FloatingActionButton({
  Key key,
  this.child,
  this.tooltip, // 长按时显示的提示
  this.foregroundColor,
  this.backgroundColor,
  this.heroTag = const _DefaultHeroTag(), //hero效果使用的tag,系统默认会给所有FAB使用同一个tag,方便做动画效果
  this.elevation,
  this.highlightElevation,
  this.disabledElevation,
  @required this.onPressed,
  this.mini = false,
  this.shape,
  this.clipBehavior = Clip.none,
  this.materialTapTargetSize,
  this.isExtended = false,
})
FloatingActionButton
FloatingActionButton

在右下角增加一个浮动按钮

代码语言:javascript
复制
floatingActionButton: FloatingActionButton(
  child: Icon(Icons.add),
  onPressed: () => {},
),

floatingActionButtonLocation

前面讲的是设置一个浮动按钮,这个浮动按钮的位置默认是在右下角。如果是要设置这个浮动按钮的位置,就需要用到FloatingActionButtonLocation

代码语言:javascript
复制
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,

persistentFooterButtons

在footer设置一系列的button,值是一个Widget list

代码语言:javascript
复制
persistentFooterButtons: <Widget>[
  Icon(Icons.satellite),
  Icon(Icons.save),
  Icon(Icons.share),
],
persistentFooterButtons
persistentFooterButtons

在设置bottomNavigationBar的时候,可能页面会很丑,我们可以放弃使用这个属性

drawer 与 endDrawer

这两个都是抽屉盒子,drawer是从左往右滑动的时候出现,endDrawer是从右往左画的时候出现

代码语言:javascript
复制
drawer: Container(
  child: Text('drawer'),
),
endDrawer: Container(
  child: Text('endDrawer'),
),
drawer
drawer

具体的内容还要自己实现。

bottomNavigationBar

在底部设置一个导航组件

代码语言:javascript
复制
bottomNavigationBar: BottomAppBar(
  shape: CircularNotchedRectangle(),
  child: Row(
    children: [
      IconButton(icon: Icon(Icons.home), onPressed: () => {}),
      SizedBox(), //中间位置空出
      IconButton(icon: Icon(Icons.business), onPressed: () => {}),
    ],
    mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间
  ),
),
bottomNavigationBar
bottomNavigationBar

可以看到这样出来的效果很丑,这是因为我们之前设置了persistentFooterButtons这个属性,占据了上面一部分空间。一般这个属性我们都不会设置的,我们把persistentFooterButtons属性注释掉在来看看。

去掉 persistentFooterButtons 后
去掉 persistentFooterButtons 后

这样看起来好看多了。

bottomSheet

底部划出组件,一般很少直接使用,而是使用showModalBottomSheet弹出,比如从底部弹出分享框。

代码语言:javascript
复制
floatingActionButton: FloatingActionButton(
  child: Icon(Icons.add),
  onPressed: () => showModalBottomSheet(
    context: context,
    builder: (BuildContext context) {
        return new Container(
            height: 300.0,
            child: Text('弹出的东东'),
        );
    },
  ).then((val) {
    print(val);
  }),
),

点击 + 按钮会弹出这个

showModalBottomSheet
showModalBottomSheet

总结

Flutter的基础的组件就讲到这里,涉及到的大都是常用的组件,部分东西没有涉及到或者说没有详细说明,可能是因为我认为不用过多说明,可能是因为没有太多时间,也可能是因为我自己也不看明白,如果你不懂,我们可以一起探讨,在评论框留言,有问题我们一起探讨。

在下面的课程中,我们将会介绍一些Flutter的中高级的Widget。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Icon
  • RaisedButton
  • Scaffold
    • AppBar
      • leading
      • automaticallyImplyLeading
      • title
      • actions
      • flexibleSapce
      • bottom
      • elevation
      • backgroundColor
      • brightness
      • centerTitle
    • body
      • floatingActionButton
        • floatingActionButtonLocation
      • persistentFooterButtons
        • drawer 与 endDrawer
          • bottomNavigationBar
            • bottomSheet
            • 总结
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档