前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文本、图片和按钮在Flutter中怎么用

文本、图片和按钮在Flutter中怎么用

作者头像
拉维
发布2019-08-12 16:01:13
7.6K0
发布2019-08-12 16:01:13
举报
文章被收录于专栏:iOS小生活iOS小生活iOS小生活

与iOS、Android和React类似,作为一个UI框架,Flutter自然也提供了很多UI控件。而文本、图片和按钮,则是这些不同的UI框架中构建视图都要用到的三个最基本的控件。

Flutter中的文本Text和图片Image,我在前面的文章中都有过介绍,今天我们再来详细地聊一聊。

文本控件

Flutter中,Text支持两种类型的文本展示,一个是默认的展示单一样式的文本 Text,另一个是支持多种混合样式的富文本 Text.rich。

我们先来看看如何使用单一样式的文本 Text

单一样式文本Text的初始化,是需要传入要展示的字符串。而这个字符串的具体展示效果,受构造函数中的其他参数控制。这些参数大致可以分为两类:

  • 控制整体文本布局的参数,如文本对齐方式 textAlign、文本排版方向 textDirection、文本显示最大行数 maxLines、文本截断规则 overFlow等,这些都是构造函数中的参数。
  • 控制文本展示样式的参数,如字体名称 fontFamily、字体大小 fontSize、文本颜色 color、文本阴影 shadows 等等,这些参数被统一封装到了构造函数中的参数 style中。

接下来,我们以一个具体的例子来看看 Text控件的使用方法。如下所示,我在代码中定义了一段居中布局、20号红色粗体展示样式的字符串:

Text(
        "这是一段居中布局、20号红色粗体展示样式的文本",
        textAlign: TextAlign.center,//居中展示
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
          color: Colors.red
        ),//20号红色粗体
      );

运行效果如下图所示:

理解了单一样式文本Text的使用方法后,我们再来看看如何在一段字符串中支持多种混合展示样式

混合展示样式与单一展示样式的关键区别在于分片,即如何把一段字符串分为几个片段来管理,给每个片段单独设置样式。面对这样的需求,在Android中,我们使用 SpannableString来实现;在iOS中,我们使用NSAttributedString来实现;而在Flutter中国也有类似的概念,即TextSpan。

TextSpan定义了一个字符串片段该如何控制其展示样式,而将这些有着独立展示样式的字符串组装在一起,则可以支持混合样式的富文本展示

如下方代码所示,我们分别定义了黑色与红色两种展示样式,随后把一段字符串分成了4个片段,并设置了不同的展示样式:

Text.rich(
        TextSpan(
          children: <TextSpan>[
            TextSpan(text: "文本是视图系统中常见的控件,它用来显示一段特定样式的字符串,类似", style: redStyle),
            TextSpan(text: "iOS", style: blackStyle),
            TextSpan(text: "中的", style: redStyle),
            TextSpan(text: "UILabel", style: blackStyle)
          ],
        ),
        textAlign: TextAlign.center,
      );

运行效果,如下图所示:

接下来,我们再来看看Flutter中的图片控件Image。

图片

使用Image,可以让我们向用户展示一张图片。图片的显示方式有很多,比如资源图片、网络图片、文件图片等,图片格式也各不相同,因此在Flutter中,也有多种方式用来加载不同形式、支持不同格式的图片:

  • 加载本地资源图片,如: Image.asset("images/001.jpg")
  • 加载网络图片,如: Image.network("http://pic39.nipic.com/20140321/18063302_210604412116_2.jpg")

除了可以根据图片的显示方式设置不同的图片源之外,图片的构造方法还提供了填充模式fit、拉伸模式centerSlice、重复模式repeat等属性,可以针对图片与目标区域的宽高比差异制定排版模式。这,和Android中的ImageView、iOS中的UIImageView的属性都是类似的,我在Flutter的图片组件这篇文章中有做详细介绍。

关于图片展示,我想和你着重分享一下Flutter中的FadeInImage控件。在加载网络图片的时候,为了提升用户的等待体验,我们往往会加入占位图、加载动画等元素,但是默认的Image.network方法并不支持这些高级功能,这个时候,FadeInImage控件就派上用场了。

FadeInImage控件提供了图片占位的功能,并且支持在图片加载完成时淡入淡出的视觉效果。此外,由于Image支持gif格式,我们甚至还可以将一些炫酷的加载动画作为占位图

下述代码展示了这样的场景。我们在加载大图片时,将一张 loading 的 gif 作为占位图展示给用户:

FadeInImage.assetNetwork(
          image: "http://pic39.nipic.com/20140321/18063302_210604412116_2.jpg",
          placeholder: "images/002.gif",//gif 占位
          width: 200,
          height: 200,
          fit: BoxFit.cover,
        );

Image控件需要根据图片资源异步加载的情况,决定自身的显示效果,因此是一个StatefulWidget。图片加载过程由 ImageProvider 触发,而 ImageProvider 表示异步获取图片数据的操作,可以从资源文件、网络等不同的渠道获取图片。

首先, ImageProvider 根据 _ImageState 中传递的图片配置,生成对应的图片缓存key,然后去ImageCache中查找是否有对应的图片缓存,如果有,则通知 _ImageState 刷新UI;如果没有,则启动ImageStream开始异步加载,加载完毕后,更新缓存;最后,通知 _ImageState 刷新UI。

Image展示图片的流程,可以用如下流程图来表示:

值得注意的是,ImageCache使用LRU(Least Recently Used,即最近最少使用)算法来进行缓存更新策略,并且默认最多存储1000张图片。最大缓存限制为100MB,当限定的空间已经存满数据时,把最久没有被访问到的图片清除。图片缓存只会在运行期间生效,也就是只缓存在内存中。如果想要支持缓存到文件系统,可以使用第三方的 CachedNetworkImage 控件(https://pub.dev/packages/cached_network_image)。

CachedNetworkImage的使用方法与 Image 类似,除了支持图片缓存之外,它还提供了比FadeInImage更为强大的加载过程占位加载错误占位

在下面的代码中,我们在加载图片时,不仅给用户展示了作为占位的转圈loading,还提供了一个错误图兜底,以备图片加载出错:

CachedNetworkImage(
        imageUrl: "http://pic27.nipic.com/20130315/11511914_151013608193_28.jpg",
        placeholder: (context, url) => new CircularProgressIndicator(),
        errorWidget: (context, url, error) => new Icon(Icons.error),
     )

最后,我们再来看看Flutter中的按钮控件。

按钮

通过按钮,我们可以响应用户的交互事件。Flutter提供了三个基本的按钮控件:FloatingActionButton、FlatButton和RaisedButton。

  • FloatingActionButton:一个圆形的按钮,一般出现在屏幕内容的前面,用来处理界面中最常用、最基础的用户动作。
  • RaisedButton:凸起的按钮,默认带有灰色背景,被点击后灰色背景会加深。
  • FlatButton:扁平化的按钮,默认透明背景,被点击后会呈现灰色背景。

这三个按钮控件的使用方法类似,唯一的区别只是默认样式不同而已。

下面代码中,我分别定义了FloatingActionButton、FlatButton和RaisedButton,它们的功能完全一样,在点击时打印一段文字:

FloatingActionButton(onPressed: () => print('FloatingActionButton pressed'),child: Text('Btn'),);
FlatButton(onPressed: () => print('FlatButton pressed'),child: Text('Btn'),);
RaisedButton(onPressed: () => print('RaisedButton pressed'),child: Text('Btn'),);

既然是按钮,因此除了控制基本样式之外,还需要响应用户点击行为。这就对应着按钮控件中两个最重要的参数了:

  • onPressed 参数用于设置点击回调,告诉Flutter在按钮点击时通知我们。如果 onPressed 参数为空,则按钮会处于禁用状态,不响应用户点击。
  • child 参数用于设置按钮的内容,告诉Flutter控件应该长成什么样,也就是控制着按钮控件的基本样式。child 可以接收任意的Widget,比如Text、Image等控件。

虽然我们可以通过 child 参数来控制按钮控件的基本样式,但是系统默认的样式还是太单调了。因此通常情况下,我们还是会进行控件样式定制

与Text控件类似,按钮控件也提供了丰富的样式定制功能,比如背景颜色color、按钮形状shape、主题颜色colorBrightness,等等。

接下来,我就以FlatButton为例,与你介绍按钮的样式定制:

FlatButton(
        child: Row( children: <Widget>[Icon(Icons.add), Text("Add")], ),
        onPressed: ()=>print("FlatButton Pressed"),
        color: Colors.yellow,//设置背景颜色为黄色
        shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(20)),//设置斜角矩形边框
        colorBrightness: Brightness.light,//确保文字按钮为深色
      );

可以看到,我们将一个加号Icon与文本组合,定义了按钮的基本外观;随后通过 shape 来指定其外形为一个斜角矩形边框,并将按钮的背景色设置为黄色。

因为按钮背景颜色是浅色的,为避免按钮文字看不清楚,我们通过设置按钮主题 colorBrightness 为 Brightness.light ,保证按钮文字颜色为深色。

展示效果如下:

总结

UI控件是构建一个视图的基本元素,而文本、图片和按钮则是其中最经典的控件。

接下来,我们简单回顾一下今天的内容,以便加深理解与记忆。

首先,我们认识了支持单一样式与混合样式两种类型的文本展示控件Text。其中,通过TextStyle控制字符串的展示样式,其他参数控制文本布局,可以实现单一样式的文本展示;而通过TextSpan将字符串分割为若干片段,对每个片段单独设置样式后组装,可以实现支持混合样式的富文本展示。

然后,我们学习了支持多种图片源加载方式的图片控件Image。Image内部通过ImageProvider根据缓存状态,触发异步加载流程,通知_ImageState刷新UI。不过,由于图片缓存是内存缓存,因此只在运行期间生效。如果要支持缓存到文件系统,可以使用第三方的CacheNetworkImage。

最后,我们学习了按钮控件,Flutter提供了多种按钮控件,而它们的使用方法也都类似。其中,控件初始化的child参数用于设置按钮长什么样,而onPressed参数则用于设置点击回调。与Text类似,按钮内部也有丰富的UI定制接口,可以满足开发者的需求。

其实,在UI基本信息的表达上,Flutter的经典控件与原生iOS、Android系统提供的控件没有什么本质区别。但是在自定义控件样式上,Flutter的这些经典控件提供了强大而简介的扩展能力,使得我们可以快速开发出功能复杂、样式丰富的页面。

以上。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档