Flutter 基础组件详解:Text、Image、Button 使用技巧

作者:爱吃大芒果
个人主页 爱吃大芒果
本文所属专栏 Flutter
更多专栏
Ascend C 算子开发教程(进阶)
鸿蒙集成
从0到1自学C++
Text、Image、Button 是 Flutter 最核心的基础 UI 组件,掌握其核心属性和实用技巧能大幅提升开发效率。本文将从基础用法 、核心属性 、实战技巧三个维度拆解这三个组件。
一、Text 组件:文本展示与样式控制
Text 用于展示静态/动态文本,核心是通过 TextStyle 控制样式,适配不同场景的文本展示需求。
1. 基础用法
最简化的用法仅需传入文本内容,Flutter 会使用默认样式(系统字体、黑色、14sp 左右):
dart
Text("Hello Flutter");
2. 核心属性
| 属性名 | 作用 |
|---|---|
style |
文本样式(核心),接收 TextStyle 对象,控制字体、颜色、大小等 |
textAlign |
文本对齐方式(left/center/right/justify 等) |
maxLines |
最大显示行数,超出后结合 overflow 处理 |
overflow |
文本溢出处理(clip/ellipsis/fade),常用 TextOverflow.ellipsis |
softWrap |
是否自动换行(true/false) |
3. 实用技巧
(1)自定义文本样式(字体、颜色、行高)
dart
Text(
"Flutter 文本样式示例",
style: TextStyle(
fontSize: 18, // 字体大小
color: Colors.blue, // 字体颜色
fontWeight: FontWeight.bold, // 字体粗细
fontFamily: "PingFangSC", // 自定义字体(需提前配置)
height: 1.5, // 行高(相对于字体大小的倍数)
decoration: TextDecoration.underline, // 下划线(lineThrough/overline)
decorationColor: Colors.red, // 装饰线颜色
letterSpacing: 2.0, // 字间距
),
textAlign: TextAlign.center, // 居中对齐
maxLines: 1, // 仅显示1行
overflow: TextOverflow.ellipsis, // 溢出省略
);
(2)富文本(不同样式混排)
单 Text 无法实现多样式混排时,使用 RichText + TextSpan:
dart
RichText(
text: TextSpan(
text: "用户名:",
style: TextStyle(color: Colors.black, fontSize: 16),
children: [
TextSpan(
text: "Flutter 开发者",
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
// 文本点击事件
recognizer: TapGestureRecognizer()..onTap = () {
print("点击了用户名");
},
),
TextSpan(
text: "(已认证)",
style: TextStyle(color: Colors.green, fontSize: 14),
),
],
),
);
(3)文本自适应容器宽度
长文本超出容器时,用 FittedBox 包裹实现自动缩放:
dart
Container(
width: 200,
height: 50,
color: Colors.grey[100],
child: FittedBox(
fit: BoxFit.scaleDown, // 仅在文本超出时缩放
child: Text("这是一段超长的文本内容,测试自适应缩放效果"),
),
);
(4)配置自定义字体
- 在项目根目录创建
fonts文件夹,放入字体文件(如PingFangSC-Regular.ttf); - 在
pubspec.yaml中配置:
yaml
flutter:
fonts:
- family: PingFangSC
fonts:
- asset: fonts/PingFangSC-Regular.ttf
- asset: fonts/PingFangSC-Bold.ttf
weight: 700
- 在
TextStyle中通过fontFamily: "PingFangSC"使用。
二、Image 组件:图片加载与展示
Image 支持加载本地资源、网络图片、本地文件、内存图片,核心是控制图片适配方式和异常处理。
1. 基础用法(不同图片源)
| 图片源 | 构造方法 | 示例 |
|---|---|---|
| 本地资源 | Image.asset() |
Image.asset("images/logo.png") |
| 网络图片 | Image.network() |
Image.network("https://xxx.png") |
| 本地文件 | Image.file() |
Image.file(File("/sdcard/xxx.png")) |
| 内存图片 | Image.memory() |
Image.memory(Uint8List bytes) |
2. 核心属性
| 属性名 | 作用 |
|---|---|
width/height |
图片宽高(仅设置一个时,按比例缩放) |
fit |
图片适配方式(核心),接收 BoxFit 枚举 |
alignment |
图片对齐方式(默认 Alignment.center) |
repeat |
图片重复方式(ImageRepeat.repeat 等,仅图片小于容器时生效) |
color/colorBlendMode |
图片叠加颜色+混合模式(如灰色滤镜) |
errorBuilder |
图片加载失败时的占位组件 |
loadingBuilder |
图片加载中时的占位组件(仅网络图片) |
cacheWidth/cacheHeight |
缓存图片尺寸(优化性能,避免加载超大图) |
3. 实用技巧
(1)图片适配方式(BoxFit 核心)
dart
Image.network(
"https://flutter.dev/images/flutter-logo-sharing.png",
width: 200,
height: 200,
// 常用适配方式:
// fit: BoxFit.contain, // 保持比例,完整显示(可能留空白)
// fit: BoxFit.cover, // 保持比例,填满容器(超出裁剪)
// fit: BoxFit.fill, // 拉伸填满(可能变形)
// fit: BoxFit.fitWidth, // 宽度填满,高度按比例
fit: BoxFit.cover,
alignment: Alignment.topCenter, // 顶部居中对齐
// 图片叠加灰色滤镜
color: Colors.grey,
colorBlendMode: BlendMode.color,
);
(2)本地图片配置(pubspec.yaml)
- 创建
images文件夹,放入图片(如logo.png); - 在
pubspec.yaml中配置:
yaml
flutter:
assets:
- images/ # 加载整个文件夹
# - images/logo.png # 加载单个图片
- 使用:
Image.asset("images/logo.png")。
(3)图片圆角/圆形处理
- 方式1:
ClipRRect包裹(圆角)
dart
ClipRRect(
borderRadius: BorderRadius.circular(10), // 圆角半径
child: Image.network(
"https://xxx.png",
width: 100,
height: 100,
fit: BoxFit.cover,
),
);
- 方式2:
ClipOval包裹(圆形,需宽高相等)
dart
ClipOval(
child: Image.network(
"https://xxx.png",
width: 100,
height: 100,
fit: BoxFit.cover,
),
);
- 方式3:
BoxDecoration(推荐,性能更好)
dart
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
image: NetworkImage("https://xxx.png"),
fit: BoxFit.cover,
),
),
);
(4)网络图片优化(加载中/失败占位、缓存)
原生 Image.network 无缓存,推荐使用 cached_network_image 插件:
- 安装:
flutter pub add cached_network_image; - 使用:
dart
CachedNetworkImage(
imageUrl: "https://xxx.png",
width: 100,
height: 100,
fit: BoxFit.cover,
// 加载中占位
placeholder: (context, url) => CircularProgressIndicator(),
// 加载失败占位
errorWidget: (context, url, error) => Icon(Icons.error, color: Colors.red),
// 缓存配置
cacheManager: CacheManager(
Config(
"custom_cache_key",
maxNrOfCacheObjects: 100, // 最大缓存数
stalePeriod: Duration(days: 7), // 缓存有效期
),
),
);
三、Button 组件:交互按钮
Flutter 提供了三类基础按钮:ElevatedButton(带阴影的凸起按钮)、TextButton(文本按钮)、OutlinedButton(边框按钮),还有 IconButton(图标按钮),核心是 onPressed 回调和样式自定义。
1. 基础用法
所有按钮的核心是 onPressed(null 时按钮禁用),child 为按钮内容:
dart
// 1. ElevatedButton(凸起按钮)
ElevatedButton(
onPressed: () { // 点击事件
print("ElevatedButton 被点击");
},
child: Text("提交"), // 按钮文本
);
// 2. TextButton(文本按钮,无背景)
TextButton(
onPressed: () {},
child: Text("取消"),
);
// 3. OutlinedButton(边框按钮)
OutlinedButton(
onPressed: () {},
child: Text("编辑"),
);
// 4. IconButton(图标按钮)
IconButton(
icon: Icon(Icons.favorite), // 图标
color: Colors.red, // 图标颜色
onPressed: () {}, // 点击事件
tooltip: "收藏", // 长按提示
);
2. 核心属性
按钮样式通过 style 属性(ButtonStyle)控制,核心配置:
| 属性名 | 作用 |
|---|---|
backgroundColor |
背景色(ElevatedButton 生效) |
foregroundColor |
前景色(文本/图标颜色) |
side |
边框样式(OutlinedButton 生效) |
shape |
按钮形状(圆角/圆形/矩形) |
padding |
内边距 |
elevation |
阴影高度(ElevatedButton 生效) |
disabledBackgroundColor |
禁用状态背景色 |
3. 实用技巧
(1)自定义按钮样式(圆角、背景色、内边距)
dart
ElevatedButton(
onPressed: () {},
child: Text("自定义按钮"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue, // 背景色
foregroundColor: Colors.white, // 文本颜色
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), // 内边距
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // 圆角
// 边框(ElevatedButton 也可加边框)
side: BorderSide(color: Colors.blueAccent, width: 1),
),
elevation: 5, // 阴影高度
minimumSize: Size(100, 44), // 最小尺寸
),
);
(2)带图标的按钮
使用 xxxButton.icon 构造方法,快速实现图标+文本按钮:
dart
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.send, size: 18), // 图标
label: Text("发送"), // 文本
style: ElevatedButton.styleFrom(
shape: CircleBorder(), // 圆形按钮(需设置固定尺寸)
fixedSize: Size(60, 60), // 固定尺寸
),
);
(3)按钮防抖(防止重复点击)
高频场景(提交表单)需防止重复点击,通过变量控制:
dart
bool _isClickable = true;
ElevatedButton(
onPressed: _isClickable
? () async {
_isClickable = false; // 禁用按钮
// 模拟接口请求
await Future.delayed(Duration(seconds: 2));
_isClickable = true; // 恢复按钮
setState(() {}); // 更新UI
}
: null, // null 表示禁用
child: Text("提交(防抖)"),
);
(4)渐变背景按钮
原生按钮无渐变属性,通过 Container + InkWell 自定义:
dart
Container(
width: 200,
height: 44,
decoration: BoxDecoration(
gradient: LinearGradient( // 渐变背景
colors: [Colors.blue, Colors.purple],
begin: Alignment.left,
end: Alignment.right,
),
borderRadius: BorderRadius.circular(22),
),
child: InkWell( // 水波纹效果
borderRadius: BorderRadius.circular(22),
onTap: () {},
child: Center(
child: Text(
"渐变按钮",
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
),
);
(5)全局按钮样式(Theme)
避免重复写样式,通过 Theme 统一配置:
dart
Theme(
data: Theme.of(context).copyWith(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
borderRadius: BorderRadius.circular(8),
),
),
),
child: ElevatedButton(
onPressed: () {},
child: Text("全局样式按钮"),
),
);
四、综合示例(Text + Image + Button)
dart
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("基础组件示例")),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Image + 圆角
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
"https://flutter.dev/images/flutter-logo-sharing.png",
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
const SizedBox(height: 20),
// Text(富文本)
RichText(
text: const TextSpan(
text: "Flutter ",
style: TextStyle(color: Colors.black, fontSize: 18),
children: [
TextSpan(
text: "基础组件",
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
),
TextSpan(text: " 实战示例"),
],
),
),
const SizedBox(height: 20),
// Button(自定义样式)
ElevatedButton.icon(
onPressed: () {
print("点击了按钮");
},
icon: const Icon(Icons.info),
label: const Text("查看详情"),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 12),
borderRadius: BorderRadius.circular(20),
),
),
],
),
),
),
);
}
}
总结
- Text :核心是
TextStyle控制样式,富文本用RichText,长文本注意溢出处理; - Image :重点是
BoxFit适配方式,网络图片推荐用缓存插件,圆角优先用BoxDecoration; - Button :优先使用系统提供的
ElevatedButton/TextButton,自定义样式用styleFrom,高频场景加防抖。
掌握这些基础用法和技巧,能满足大部分日常 UI 开发需求,后续可结合布局组件(Row/Column/Container)实现更复杂的界面。