Flutter for OpenHarmony 视力保护提醒App实战 - flutter_screenutil屏幕适配
本文介绍了Flutter屏幕适配库flutter_screenutil的核心功能和使用方法。该库通过设计尺寸设置、单位转换和文本缩放等功能,实现不同设备屏幕的UI适配。文章详细讲解了项目依赖配置、ScreenUtilInit初始化过程,以及.w/.h/.sp三种单位转换方法的使用场景和示例代码。这些功能共同构建了一个完整的屏幕适配解决方案,帮助开发者在不同尺寸设备上保持UI一致性,大大简化了响应式

概述
flutter_screenutil是一个强大的屏幕适配库,它可以帮助开发者轻松地实现在不同屏幕尺寸的设备上的UI适配。在视力保护提醒应用中,我们使用flutter_screenutil来确保UI在各种设备上都能正确显示。本文将详细讲解如何使用flutter_screenutil进行屏幕适配,包括设计尺寸设置、单位转换、响应式设计等功能。屏幕适配是现代移动应用开发的重要课题,因为用户使用的设备屏幕尺寸差异很大,从小屏幕手机到大屏幕平板电脑。
flutter_screenutil的核心功能
flutter_screenutil主要提供以下功能:
-
设计尺寸设置 - 定义设计稿的尺寸,通常是375x812(iPhone 11的尺寸)。这个尺寸作为基准,所有的单位转换都基于这个尺寸进行计算。
-
单位转换 - 自动将设计尺寸转换为实际屏幕尺寸。通过使用
.w、.h、.sp等扩展方法,我们可以轻松地将设计尺寸转换为实际像素值。 -
文本缩放 - 根据屏幕尺寸自动调整文本大小。这确保了文本在不同屏幕尺寸上都能保持可读性。
-
响应式设计 - 支持不同屏幕方向和尺寸。通过使用LayoutBuilder和MediaQuery,我们可以根据屏幕尺寸和方向选择不同的布局。
这些功能结合在一起,为应用提供了一个完整的屏幕适配解决方案。相比于手动计算像素值,使用flutter_screenutil可以大大简化开发过程。
项目依赖配置
在pubspec.yaml中,我们已经配置了所需的依赖:
dependencies:
flutter:
sdk: flutter
flutter_screenutil: ^5.9.0
get: ^4.6.5
shared_preferences: ^2.2.2
代码说明:flutter_screenutil库提供了屏幕适配功能。这个依赖是为了支持鸿蒙系统的Flutter开发。通过在pubspec.yaml中声明这个依赖,我们可以在项目中使用flutter_screenutil提供的所有功能。get库用于状态管理,shared_preferences用于本地存储。这些依赖共同构成了应用的基础框架。
依赖配置是项目开发的基础,正确的依赖配置确保了项目能够正常运行。
ScreenUtilInit初始化
在应用的main.dart中,我们使用ScreenUtilInit来初始化flutter_screenutil。这是使用flutter_screenutil的第一步,必须在应用启动时进行初始化。
应用入口和初始化
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
splitScreenMode: true,
builder: (context, child) {
return GetMaterialApp(
title: '视力保护助手',
debugShowCheckedModeBanner: false,
代码说明:
ScreenUtilInit是flutter_screenutil提供的初始化组件。designSize参数定义了设计稿的尺寸,通常是375x812(iPhone 11的尺寸)。minTextAdapt参数设置为true,表示启用文本自适应。splitScreenMode参数设置为true,表示支持分屏模式。builder方法返回应用的根Widget。通过这种方式,我们可以确保整个应用都能使用flutter_screenutil的屏幕适配功能。
初始化是使用flutter_screenutil的关键步骤。通过正确的初始化,我们可以确保应用的所有UI元素都能正确适配。
应用主题配置
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: const Color(0xFF2196F3),
scaffoldBackgroundColor: const Color(0xFFF5F5F5),
appBarTheme: const AppBarTheme(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
elevation: 0.5,
centerTitle: true,
),
textTheme: TextTheme(
displayLarge: TextStyle(fontSize: 32.sp, fontWeight: FontWeight.bold),
displayMedium: TextStyle(fontSize: 28.sp, fontWeight: FontWeight.bold),
titleLarge: TextStyle(fontSize: 20.sp, fontWeight: FontWeight.bold),
bodyLarge: TextStyle(fontSize: 16.sp),
bodyMedium: TextStyle(fontSize: 14.sp),
bodySmall: TextStyle(fontSize: 12.sp),
),
),
home: const MainPage(),
);
},
);
}
}
代码说明:在
ThemeData中配置应用的主题。primaryColor定义了应用的主色调。scaffoldBackgroundColor定义了页面的背景颜色。appBarTheme定义了AppBar的样式。textTheme定义了应用中使用的文本样式。通过在textTheme中使用.sp单位,我们可以确保文本在不同屏幕尺寸上都能正确显示。这种集中的主题配置使应用的样式更加一致和易于维护。
主题配置是应用设计的重要部分。通过集中配置主题,我们可以确保应用的整体风格一致。
单位转换
flutter_screenutil提供了多个单位转换方法。这些方法是flutter_screenutil的核心功能,通过这些方法,我们可以轻松地将设计尺寸转换为实际屏幕尺寸。
宽度单位 (.w)
// 基本用法
EdgeInsets.all(16.w) // 16个宽度单位
Padding(padding: EdgeInsets.symmetric(horizontal: 12.w)) // 12个宽度单位
// 在Container中使用
Container(
width: 100.w,
height: 50.h,
margin: EdgeInsets.all(16.w),
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.w),
),
)
// 在SizedBox中使用
SizedBox(width: 200.w, height: 100.h)
代码说明:
.w表示宽度单位。例如,16.w表示16个宽度单位,会根据实际屏幕宽度自动转换为实际像素值。计算公式是:实际像素值 = 设计值 × (实际屏幕宽度 / 设计屏幕宽度)。这种设计使得UI在不同屏幕宽度的设备上都能保持相同的相对大小。通过使用宽度单位,我们可以确保应用在各种设备上都能正确显示。
宽度单位是flutter_screenutil最常用的单位。通过使用宽度单位,我们可以确保UI元素在不同屏幕宽度上的相对大小保持一致。
高度单位 (.h)
// 基本用法
SizedBox(height: 16.h) // 16个高度单位
EdgeInsets.symmetric(vertical: 8.h) // 8个高度单位
// 在Column中使用
Column(
children: [
Container(height: 100.h, color: Colors.red),
SizedBox(height: 16.h),
Container(height: 100.h, color: Colors.blue),
SizedBox(height: 16.h),
Container(height: 100.h, color: Colors.green),
],
)
// 在ListView中使用
ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Container(
height: 80.h,
margin: EdgeInsets.symmetric(vertical: 8.h),
color: Colors.grey[300],
);
},
)
代码说明:
.h表示高度单位。例如,16.h表示16个高度单位,会根据实际屏幕高度自动转换为实际像素值。计算公式是:实际像素值 = 设计值 × (实际屏幕高度 / 设计屏幕高度)。这种设计使得UI在不同屏幕高度的设备上都能保持相同的相对大小。通过使用高度单位,我们可以确保应用在各种设备上都能正确显示。
高度单位用于控制UI元素的垂直大小。通过使用高度单位,我们可以确保UI元素在不同屏幕高度上的相对大小保持一致。
字体大小单位 (.sp)
// 基本用法
TextStyle(fontSize: 16.sp) // 16个字体单位
Icon(Icons.home, size: 24.sp) // 24个字体单位
// 在Text中使用
Text(
'视力保护提醒',
style: TextStyle(
fontSize: 20.sp,
fontWeight: FontWeight.bold,
color: Colors.black,
),
)
// 在AppBar中使用
AppBar(
title: Text(
'首页',
style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.bold),
),
elevation: 0,
)
// 在Button中使用
ElevatedButton(
onPressed: () {},
child: Text(
'开始',
style: TextStyle(fontSize: 16.sp),
),
)
代码说明:
.sp表示字体大小单位。例如,16.sp表示16个字体单位,会根据实际屏幕尺寸自动转换为实际字体大小。这种设计使得文本在不同屏幕尺寸的设备上都能保持可读性。通过使用字体大小单位,我们可以确保应用的文本在各种设备上都能正确显示。字体大小单位还考虑了系统的文本缩放设置,确保了无障碍访问。
字体大小单位是确保文本可读性的关键。通过使用字体大小单位,我们可以确保文本在不同屏幕尺寸上都能保持可读性。
实际应用示例
在应用中,我们广泛使用这些单位转换方法。例如,在月统计页面中:
月统计概览卡片
Widget _buildMonthlyOverview() {
return Container(
margin: EdgeInsets.all(16.w),
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'本月概览',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildOverviewItem('总提醒', '224次', const Color(0xFF2196F3)),
_buildOverviewItem('总休息', '1120分', const Color(0xFF4CAF50)),
_buildOverviewItem('平均评分', '8.1', const Color(0xFFFFC107)),
],
),
],
),
);
}
Widget _buildOverviewItem(String label, String value, Color color) {
return Column(
children: [
Text(
value,
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
color: color,
),
),
SizedBox(height: 4.h),
Text(
label,
style: TextStyle(fontSize: 12.sp, color: Colors.grey),
),
],
);
}
代码说明:这段代码实现了月统计概览卡片的构建。通过组合多个Flutter Widget组件,我们可以创建复杂的用户界面。Container创建白色卡片,使用margin和padding设置边距。BoxDecoration定义卡片的样式,包括白色背景、圆角和阴影。Column竖直排列标题和数据行。Row使用mainAxisAlignment: MainAxisAlignment.spaceAround均匀分布三个数据项。通过使用
.w、.h、.sp等单位,我们可以确保UI在不同屏幕尺寸上都能正确显示。
实际应用示例展示了如何在真实项目中使用flutter_screenutil。
响应式设计
使用flutter_screenutil可以轻松实现响应式设计。响应式设计是指应用能够根据屏幕尺寸和方向自动调整布局。
LayoutBuilder实现响应式布局
Widget _buildResponsiveLayout() {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
// 宽屏设备布局(平板电脑)
return Row(
children: [
Expanded(
flex: 1,
child: _buildLeftPanel(),
),
SizedBox(width: 16.w),
Expanded(
flex: 1,
child: _buildRightPanel(),
),
],
);
} else {
// 窄屏设备布局(手机)
return Column(
children: [
_buildLeftPanel(),
SizedBox(height: 16.h),
_buildRightPanel(),
],
);
}
},
);
}
Widget _buildLeftPanel() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
children: [
Text('左侧面板', style: TextStyle(fontSize: 16.sp)),
],
),
);
}
Widget _buildRightPanel() {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
children: [
Text('右侧面板', style: TextStyle(fontSize: 16.sp)),
],
),
);
}
代码说明:
LayoutBuilder提供了constraints参数,包含了可用的最大宽度和高度。根据maxWidth的值,我们可以选择不同的布局。当屏幕宽度大于600时,使用行布局(Row)来并排显示两个面板。当屏幕宽度小于等于600时,使用列布局(Column)来垂直显示两个面板。这种设计确保了应用在各种屏幕尺寸上都能正确显示。
响应式布局是现代应用设计的重要特性。通过使用LayoutBuilder,我们可以根据屏幕尺寸选择不同的布局。
屏幕方向适配是确保应用在各种使用场景下都能正确显示的关键。
常见单位转换
在应用中,我们经常使用以下单位转换:
边距和大小转换
// 边距
EdgeInsets.all(16.w)
EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h)
EdgeInsets.only(left: 16.w, top: 12.h, right: 16.w, bottom: 12.h)
// 大小
SizedBox(width: 100.w, height: 50.h)
Container(width: 80.w, height: 80.w)
// 圆角
BorderRadius.circular(12.r)
BorderRadius.only(
topLeft: Radius.circular(12.r),
topRight: Radius.circular(12.r),
)
// 阴影
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
)
代码说明:这些代码展示了如何使用flutter_screenutil的单位转换来设置边距和大小。
EdgeInsets.all(16.w)设置四周边距为16个宽度单位。EdgeInsets.symmetric()设置对称的边距。SizedBox和Container使用宽度和高度单位来设置大小。BorderRadius.circular(12.r)设置圆角半径为12个宽度单位。这种设计确保了UI在不同屏幕尺寸上的一致性。
常见单位转换是开发中最常用的操作。通过掌握这些常见的转换方式,我们可以快速地构建响应式UI。
圆角和字体转换
// 圆角
BorderRadius.circular(12.r)
BorderRadius.only(topLeft: Radius.circular(12.r))
// 字体
TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold)
Icon(Icons.home, size: 24.sp)
// 按钮
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 12.h),
),
child: Text('按钮', style: TextStyle(fontSize: 16.sp)),
)
代码说明:这些代码展示了如何使用flutter_screenutil的单位转换来设置圆角、字体和按钮样式。
BorderRadius.circular(12.r)设置圆角半径为12个宽度单位。TextStyle(fontSize: 16.sp)设置字体大小为16个字体单位。Icon(Icons.home, size: 24.sp)设置图标大小为24个字体单位。通过使用这些单位转换,我们可以确保UI元素在不同屏幕尺寸上的正确显示。
字体和圆角的转换是UI设计的重要部分。通过正确地使用这些转换,我们可以创建美观的UI。
总结
flutter_screenutil是一个强大的屏幕适配库,它可以帮助开发者轻松地实现在不同屏幕尺寸的设备上的UI适配。通过定义设计尺寸、使用单位转换方法、实现响应式设计,我们可以确保应用在各种设备上都能正确显示。
在视力保护提醒应用中,我们使用flutter_screenutil来确保UI在各种设备上都能正确显示。这样可以提高应用的用户体验,使应用在不同设备上都能保持一致的外观和感觉。通过正确地使用flutter_screenutil,我们可以构建高质量的跨平台应用。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)