在这里插入图片描述

概述

flutter_screenutil是一个强大的屏幕适配库,它可以帮助开发者轻松地实现在不同屏幕尺寸的设备上的UI适配。在视力保护提醒应用中,我们使用flutter_screenutil来确保UI在各种设备上都能正确显示。本文将详细讲解如何使用flutter_screenutil进行屏幕适配,包括设计尺寸设置、单位转换、响应式设计等功能。屏幕适配是现代移动应用开发的重要课题,因为用户使用的设备屏幕尺寸差异很大,从小屏幕手机到大屏幕平板电脑。

flutter_screenutil的核心功能

flutter_screenutil主要提供以下功能:

  1. 设计尺寸设置 - 定义设计稿的尺寸,通常是375x812(iPhone 11的尺寸)。这个尺寸作为基准,所有的单位转换都基于这个尺寸进行计算。

  2. 单位转换 - 自动将设计尺寸转换为实际屏幕尺寸。通过使用.w.h.sp等扩展方法,我们可以轻松地将设计尺寸转换为实际像素值。

  3. 文本缩放 - 根据屏幕尺寸自动调整文本大小。这确保了文本在不同屏幕尺寸上都能保持可读性。

  4. 响应式设计 - 支持不同屏幕方向和尺寸。通过使用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()设置对称的边距。SizedBoxContainer使用宽度和高度单位来设置大小。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

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐