图片和图标
Image 图片组件
Flutter 中,我们可以通过 Image 组件来加载并显示图片 Image 的数据源可以是 asset、文件、内存以及网络
- Image.asset, 本地图片
- Image.network 远程图片
Image 常用属性
名称 | 类型 | 说明 |
---|---|---|
alignment | Alignment | 图片的对齐方式 |
color 和 colorBlendMode | 设置图片的背景颜色,通常和 colorBlendMode 配合一起使用,这样可以是图片颜色和背景色混合。上面的图片就是进行了颜色的混合,绿色背景和图片红色的混合 | |
fit | BoxFit | fit 属性用来控制图片的拉伸和挤压,这都是根据父容器来 的。 BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。 BoxFit.contain:全图显示,显示原比例,可能会有空隙。 BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。 BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。 BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。 BoxFit.scaleDown:效果和 contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大。 |
repeat | 平铺 | ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。ImageRepeat.repeatX: 横向重复,纵向不重复。 ImageRepeat.repeatY:纵向重复,横向不重复。 |
width | 宽度 一般结合 ClipOval 才能看到效果 | |
height | 高度 一般结合 ClipOval 才能看到效果 |
加载远程图片
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: [
// 网络图片
Container(
alignment: Alignment.center,
width: 150,
height: 150,
margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
decoration: const BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.all(Radius.circular(75)),
),
child: ClipOval(
child: Image.network(
"https://doc.ronhai.com/bg.png",
fit: BoxFit.cover,
width: 150,
height: 150,
),
),
),
// Container实现圆形图片
const SizedBox(
height: 20,
),
],
),
);
}
}
Container 实现圆形图片
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(75),
image: const DecorationImage(
image: NetworkImage('https://doc.ronhai.com/bg.png'),
fit: BoxFit.cover)),
)
],
),
);
}
}
ClipOval 实现圆形图片
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
ClipOval(
child: Image.network(
'https://www.ronhai.com/media/images/article/flutter.png',
fit: BoxFit.cover,
width: 45,
height: 45,
)),
],
),
);
}
}
CircleAvatar 实现圆形图片
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Column(
children: [
CircleAvatar(
radius: 100,
backgroundImage: NetworkImage(
'https://www.ronhai.com/media/images/article/flutter.png'),
)
],
),
);
}
}
基本上,CircleAvatar 不提供设置边框的属性。但是,可以将其包裹在具有更大半径和不同背景颜色的 不同 CircleAvatar 中,以创建类似于边框的内容
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Column(
children: [
CircleAvatar(
radius: 110,
backgroundColor: Colors.red,
child: CircleAvatar(
radius: 80,
backgroundImage: NetworkImage(
'https://www.ronhai.com/media/images/article/flutter.png'),
),
)
],
),
);
}
}
加载本地图片
在项目的根目录新建 images 放入本地图片,设置pubspec.yaml
的assets
yaml
name: flutter_image
description: "A new Flutter project."
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ^3.5.4
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
flutter:
uses-material-design: true
#本地图片设置
assets:
- images/2.jpg
- images/avatar.jpg
- images/bannar.jpg
- images/travel.jpg
- images/web.jpg
使用
dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Column(
children: [
// 本地图片
Icon(Icons.home),
SizedBox(
height: 20,
),
Icon(
Icons.people,
color: Colors.pink,
),
],
),
);
}
}
图标组件
使用 Flutter 官方 Icons 图标
Material Design 所有图标可以在其官网查看:https://material.io/tools/icons/
阿里巴巴图标库
Flutter 中借助阿里巴巴图标库自定义字体图标
我们也可以使用自定义字体图标。阿里巴巴图标库官网 iconfont.cn 上有很多字体图标素材,我们可以选择自己需要的图标打包下载后,会生成一些不同格式的字体文件,在 Flutter 中,我们使用 ttf 格式即可。
假设我们项目中需要使用一套图标,我们打包下载后导入
也可以配置多个字体文件
dart
fonts:
- family: iconfont
fonts:
- asset: assets/fonts/iconfont.ttf
- family: myicon
fonts:
- asset: assets/fonts/myicon.ttf
为了使用方便,我们定义一个 MyIcons 类,功能和 Icons 类一样:将字体文件中的所有图标都定义成静态变量
dart
import 'package:flutter/material.dart';
class IconFont {
static const IconData view = IconData(
0xe633,
fontFamily: 'iconfont',
matchTextDirection: true,
);
static const IconData message = IconData(
0xe635,
fontFamily: 'iconfont',
matchTextDirection: true,
);
}
使用
dart
import 'package:flutter/material.dart';
import 'common/iconfont.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo'),
),
body: Center(
child: Container(
alignment: Alignment.center,
width: 300,
height: 300,
child: const Column(
children: [
Icon(
IconFont.view,
size: 30,
color: Colors.amber,
),
Icon(
IconFont.message,
size: 30,
color: Colors.amber,
)
],
)),
)),
);
}
}
脚本生成 iconfont.dart 文件
新建generate_icons.dart
文件放入 common 文件夹中,增加以下内容:
使用Code Runner
运行脚本即可
dart
import 'dart:convert';
import 'dart:io';
String toCamelCase(String name) {
List<String> parts = name.split(RegExp(r'[-_]'));
String camelCaseName = parts[0];
for (int i = 1; i < parts.length; i++) {
camelCaseName += parts[i][0].toUpperCase() + parts[i].substring(1);
}
return camelCaseName;
}
void generateIconFontClass(String jsonFilePath, String outputFilePath) {
File jsonFile = File(jsonFilePath);
if (!jsonFile.existsSync()) {
print('JSON file not found: $jsonFilePath');
return;
}
String jsonString = jsonFile.readAsStringSync();
Map<String, dynamic> jsonData = jsonDecode(jsonString);
StringBuffer buffer = StringBuffer();
buffer.writeln("import 'package:flutter/material.dart';\n");
buffer.writeln("class IconFont {");
if (jsonData.containsKey('glyphs')) {
List<dynamic> glyphs = jsonData['glyphs'];
glyphs.forEach((glyph) {
if (glyph.containsKey('unicode_decimal') && glyph.containsKey('name')) {
String name = glyph['name'];
int unicode = glyph['unicode_decimal'];
// String fontClass = glyph['font_class'];
String fieldName = toCamelCase(name);
buffer.writeln(" static const IconData $fieldName = IconData(");
buffer.writeln(" 0x${unicode.toRadixString(16)},");
buffer.writeln(" fontFamily: 'iconfont',");
buffer.writeln(" matchTextDirection: true,");
buffer.writeln(" );");
}
});
}
buffer.writeln("}");
// Write generated code to output file
File outputFile = File(outputFilePath);
outputFile.writeAsStringSync(buffer.toString());
print('IconFont class generated successfully at: $outputFilePath');
}
void main() {
String jsonFilePath = 'assets/fonts/iconfont.json';
String outputFilePath = 'lib/common/iconfont.dart';
generateIconFontClass(jsonFilePath, outputFilePath);
}
引用
dart
const Icon(
IconFont.view,
color: Colors.red,
size: 30,
)