Flutter基础控件之[文本/图片/按钮]

image-20210412211728803

文本控件

文本是视图系统中的常见控件,用来显示一段特定样式的字符串,就比如 Android 里的TextView、iOS 中的 UILabel。而在 Flutter 中,文本展示是通过 Text 控件实现的。

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

单一文本Text

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

  • 控制整体文本布局的参数

    如文本对齐方式 textAlign、文本排版方向 textDirection,文本显示最大行数 maxLines、文本截断规则 overflow 等等,这些都是构造函数中的参数;

  • 控制文本展示样式的参数

    如字体名称 fontFamily、字体大小 fontSize、文本颜色color、文本阴影 shadows 等等,这些参数被统一封装到了构造函数中的参数 style 中。

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

    Text(
    	"自定义文本",
    	textAlign: TextAlign.center,
    	style: TextStyle(backgroundColor: Colors.deepOrange,fontSize: 20)
    )
    //运行结果如下图
    

    image-20210413095714400

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

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

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

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

TextStyle blackStyle = TextStyle(fontWeight: FontWeight.normal,fontSize: 20,color: Colors.black);

TextStyle greenStyle = TextStyle(fontWeight: FontWeight.bold,fontSize: 30,color: Colors.green);

Text.rich(
	TextSpan(
		children: <TextSpan>[
		TextSpan(text: "文本是视图系统中最常dart见的控件,它用来显示一段特定样式的字符串"),
		TextSpan(text: "Android\n",style: blackStyle),
		TextSpan(text: "IOS",style: greenStyle),
		]
	),
	textAlign: TextAlign.center
)

image-20210413101353218


图片

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

  • 加载本地资源图片,如 Image.asset(‘images/logo.png’);
  • 加载本地(File 文件)图片,如 Image.file(newFile(’/storage/xxx/xxx/test.jpg’));
  • 加载网络图片,如 Image.network(‘http://xxx/xxx/test.gif’)

除了可以根据图片的显示方式设置不同的图片源之外,图片的构造方法还提供了填充模式fit、拉伸模式 centerSlice、重复模式 repeat 等属性,可以针对图片与目标区域的宽高比差异制定排版模式。

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

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

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

FadeInImage.assetNetwork(
	placeholder: 'assets/loading.gif',
	image:   'https://tva1.sinaimg.cn/large/008eGmZEgy1gphz4wmf72g30ia0dq76h.gif',
	fit: BoxFit.cover,
	width: 200,
	height: 200,
),

image-20210413123251888

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

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

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

image-20210413141844485

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

CachedNetworkImage 的使用方法与 Image 类似,除了支持图片缓存外,还提供了比FadeInImage 更为强大的加载过程占位与加载错误占位,可以支持比用图片占位更灵活的自定义控件占位。

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

CachedNetworkImage(
	imageUrl: "http://x.jpg",
  placeholder: (context,url) => CircularProgressIndicator(),
  errorWidget: (context,url,error) => Icon(Icons.error)
)

按钮

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

  1. FloatingActionButton
  2. FlatButton
  3. RaisedButton。
  • FloatingActionButton
    • 一个圆形的按钮,一般出现在屏幕内容的前面,用来处理界面中最常用、最基础的用户动作。在之前的第 5 篇文章“从标准模板入手,体会 Flutter 代码是如何运行在原生系统上的”中,计数器示例的“+”悬浮按钮就是一个FloatingActionButton。
  • FlatButton
    • 扁平化的按钮,默认透明背景,被点击后会呈现灰色背景。
  • RaisedButton
    • 凸起的按钮,默认带有灰色背景,被点击后灰色背景会加深。

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

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

FloatingActionButton(onPressed: ()=>print("FloatingActionButton pressed!"),child: Text("Btn_1")),

FlatButton(onPressed: ()=>print("FlatButton pressed!"),child: Text("Btn_2")),

RaisedButton(onPressed: ()=>print("RaisedButton pressed!"),child: Text("Btn_3")),

image-20210413143829426

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

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

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

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

FlatButton(
	shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
	onPressed: () => print("Rush B!!"),
	child: Row(children: <Widget>[
		Icon(Icons.accessible_forward_sharp),
		Text("Tap to Rush B!!"),
	],),
	color: Colors.deepOrange,
	colorBrightness: Brightness.light
)

image-20210413144819907

总结

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值