Flutter色彩障碍辅助插件color_blindness的使用
Flutter色彩障碍辅助插件 color_blindness
的使用
在开发Flutter应用时,确保应用程序的颜色对所有用户都具有可访问性是非常重要的。为了帮助开发者更好地实现这一目标,可以使用 color_blindness
插件来模拟色盲效果,并进行对比度测试。
插件功能
- 更改整个主题:通过包装
ColorScheme
来调用colorBlindnessColorScheme()
。 - 用于CI测试:使用
colorBlindnessAssertContrast()
进行对比度测试。 - 修改单个颜色:可以通过
colorBlindness()
或直接调用特定的方法(如tritanopia()
)来修改单个颜色。
使用步骤
添加依赖
首先,在你的 pubspec.yaml
文件中添加 color_blindness
依赖:
dependencies:
color_blindness: ^VERSION
请将 ^VERSION
替换为最新版本号。
包装 ColorScheme
在你的项目中,只需将 ColorScheme.dark(...)
包装到 colorBlindnessColorScheme()
中:
import 'package:color_blindness/color_blindness.dart';
Theme(
data: ThemeData(
colorScheme: colorBlindnessColorScheme(ColorScheme.dark(), ColorBlindnessType.tritanopia),
),
child: MyApp(),
)
CI 测试
你可以添加一个测试来确保 ColorScheme
始终是可访问的。第二个参数是 WCAG 最小阈值,通常至少为 4.5:
colorScheme = ColorScheme.light(
primary: const Color(0xff9f0042),
secondary: const Color(0xff1e6100),
);
expect(() => colorBlindnessAssertContrast(colorScheme, 4.0), returnsNormally);
修改单个颜色
你可以使用 colorBlindness()
并传入 ColorBlindnessType
作为第二个参数,或者直接调用方法:
const primary = const Color(0xff9f0042);
// 间接方式
colorBlindness(primary, ColorBlindnessType.tritanopia);
// 直接方式
tritanopia(primary);
示例 Demo
以下是一个完整的示例,展示了如何在实际项目中使用 color_blindness
插件:
import 'package:color_blindness/color_blindness.dart';
import 'package:flutter/material.dart';
import 'package:random_color_scheme/random_color_scheme.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Color Blindness',
home: const RefreshableHome(),
theme: ThemeData(
colorScheme: const ColorScheme.light(
primary: Color(0xffC2410C),
),
),
);
}
}
class RefreshableHome extends StatelessWidget {
const RefreshableHome({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: const ThemeScreen(),
appBar: AppBar(
backgroundColor: Colors.white,
title: const Text(
"Color Blindness Color Scheme",
style: TextStyle(color: Colors.black),
),
actions: [
IconButton(
icon: const Icon(Icons.code_rounded, color: Colors.black),
tooltip: "Source",
onPressed: () async {
await launchUrl(Uri.parse("https://github.com/bernaferrari/ColorBlindnessFlutter"));
},
)
],
elevation: 0,
),
);
}
}
class ThemeScreen extends StatefulWidget {
const ThemeScreen({Key? key}) : super(key: key);
[@override](/user/override)
State<ThemeScreen> createState() => _ThemeScreenState();
}
class _ThemeScreenState extends State<ThemeScreen> {
double sliderValue = 0;
ColorBlindnessType typeSelected = ColorBlindnessType.none;
int seed = 0;
Theme customThemeChild({required int i, required bool isDark}) {
return Theme(
data: ThemeData(
colorScheme: colorBlindnessColorScheme(
randomColorScheme(seed: i + seed, isDark: isDark, shouldPrint: false),
typeSelected,
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
),
cardTheme: CardTheme(
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
),
child: const ThemeItem(),
);
}
String typesToStr() {
final str = typeSelected.toString().substring(19);
return str[0].toUpperCase() + str.substring(1);
}
String affectedToStr() {
const m = "of males";
const f = "of females";
const p = "of population";
switch (typeSelected) {
case ColorBlindnessType.none:
return "most of the population";
case ColorBlindnessType.protanomaly:
return "1% $m, 01% $f";
case ColorBlindnessType.deuteranomaly:
return "6% $m, 0.4% $f";
case ColorBlindnessType.tritanomaly:
return "01% $p";
case ColorBlindnessType.protanopia:
return "1% $m";
case ColorBlindnessType.deuteranopia:
return "1% $m";
case ColorBlindnessType.tritanopia:
return "less than 1% $p";
case ColorBlindnessType.achromatopsia:
return "003% $p";
case ColorBlindnessType.achromatomaly:
return "001% $p";
default:
return "";
}
}
[@override](/user/override)
Widget build(BuildContext context) {
final condition = MediaQuery.of(context).size.width > 950;
return Padding(
padding: const EdgeInsets.all(4),
child: SingleChildScrollView(
child: Column(
children: [
Card(
elevation: 0,
color: const Color(0xffFFF7ED),
shape: RoundedRectangleBorder(
side: const BorderSide(width: 2, color: Color(0xffFED7AA)),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
"""
This is the sample for a library.
The idea is for you to plug colorBlindnessColorScheme() into your apps.""",
style: Theme.of(context).textTheme.titleSmall,
textAlign: TextAlign.center,
),
),
),
const SizedBox(height: 24),
Text(
typesToStr(),
style: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
),
Text(
affectedToStr(),
style: Theme.of(context).textTheme.titleSmall,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Slider(
min: 0,
max: 7,
divisions: 7,
value: sliderValue,
onChanged: (value) {
setState(() {
sliderValue = value;
typeSelected = ColorBlindnessType.values[sliderValue.toInt()];
});
},
),
),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
label: const Text("Randomize Themes"),
icon: const Icon(Icons.shuffle_rounded, size: 16),
onPressed: () {
setState(() {
seed += 4;
});
},
),
const SizedBox(height: 16),
for (int i = 0; i < 3; i++)
Flex(
direction: condition ? Axis.horizontal : Axis.vertical,
children: [
Flexible(
flex: condition ? 1 : 0,
child: customThemeChild(i: i, isDark: true),
),
Flexible(
flex: condition ? 1 : 0,
child: customThemeChild(i: i, isDark: false),
),
],
),
],
),
),
);
}
}
class ThemeItem extends StatelessWidget {
const ThemeItem({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Card(
color: Theme.of(context).colorScheme.surface,
elevation: 0,
child: const Row(
children: [
Expanded(child: SocialPreview()),
Expanded(child: ChatPreview()),
],
),
);
}
}
更多关于Flutter色彩障碍辅助插件color_blindness的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter色彩障碍辅助插件color_blindness的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中集成和使用color_blindness
插件的一个示例。这个插件可以帮助你调整应用的色彩方案,以更好地支持色盲用户。
首先,你需要在pubspec.yaml
文件中添加color_blindness
依赖:
dependencies:
flutter:
sdk: flutter
color_blindness: ^latest_version # 请替换为最新的版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Dart代码中,你可以按照以下步骤来使用这个插件:
- 导入包:
import 'package:flutter/material.dart';
import 'package:color_blindness/color_blindness.dart';
- 定义一个辅助函数来调整颜色:
你可以创建一个函数来调整颜色,以适应不同的色盲类型。例如:
Color adjustColorForColorBlindness(Color color, ColorBlindnessType type) {
ColorBlindness colorBlindness = ColorBlindness(type);
return colorBlindness.transform(color);
}
- 在Widget中使用调整后的颜色:
下面是一个简单的示例,展示如何在Container
中使用调整后的颜色:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Color Blindness Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 100,
color: adjustColorForColorBlindness(Colors.red, ColorBlindnessType.protanopia),
child: Center(child: Text('Protanopia')),
),
SizedBox(height: 20),
Container(
width: 100,
height: 100,
color: adjustColorForColorBlindness(Colors.red, ColorBlindnessType.deuteranopia),
child: Center(child: Text('Deuteranopia')),
),
SizedBox(height: 20),
Container(
width: 100,
height: 100,
color: adjustColorForColorBlindness(Colors.red, ColorBlindnessType.tritanopia),
child: Center(child: Text('Tritanopia')),
),
],
),
),
),
);
}
}
在这个示例中,我们定义了三个不同颜色的Container
,每个Container
都使用adjustColorForColorBlindness
函数来调整颜色,以适应不同类型的色盲(红色盲、绿色盲和蓝色盲)。
注意:ColorBlindnessType
是一个枚举,包含了不同的色盲类型,例如protanopia
(红色盲)、deuteranopia
(绿色盲)和tritanopia
(蓝色盲)等。
这个示例展示了如何在Flutter应用中使用color_blindness
插件来调整颜色,以提高应用对色盲用户的友好性。你可以根据具体需求进一步扩展这个示例。