Flutter屏幕适配插件flutter_screenfit的使用

Flutter屏幕适配插件flutter_screenutil的使用

flutter_screenutil简介

flutter_screenutil 是一个用于屏幕适配和字体大小调整的Flutter插件。它可以帮助您的UI在不同屏幕尺寸上合理布局。

特性:

  • 支持屏幕宽度和高度的适配。
  • 支持字体大小的适配,并可根据系统字体缩放选项动态调整。
  • 提供便捷的扩展方法(从Dart SDK 2.6开始支持)。

使用步骤

1. 添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  # 添加 flutter_screenutil
  flutter_screenutil: ^{最新版本}

运行 flutter pub get 安装依赖。


2. 导入插件

在需要使用的文件中导入插件:

import 'package:flutter_screenutil/flutter_screenutil.dart';

初始化与设置

方法一:直接在 MaterialApp 中初始化

推荐此方法,因为它可以在全局范围内进行适配。

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 设置适配尺寸(设计稿的设备尺寸,单位为dp)
    return ScreenUtilInit(
      designSize: Size(360, 690), // 设计稿尺寸为360x690
      builder: () => MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter_ScreenUtil',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          textTheme: TextTheme(
            // 字体适配
            button: TextStyle(fontSize: 45.sp),
          ),
        ),
      ),
    );
  }
}

方法二:通过 ScreenUtil.init() 初始化

不推荐此方法,因为无法在 MaterialApptextTheme 中支持字体适配。

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter_ScreenUtil',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(title: 'FlutterScreenUtil Demo'),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key key, this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 设置适配尺寸
    ScreenUtil.init(
      BoxConstraints(
        maxWidth: MediaQuery.of(context).size.width,
        maxHeight: MediaQuery.of(context).size.height,
      ),
      designSize: Size(360, 690),
      orientation: Orientation.portrait,
    );
    return Scaffold();
  }
}

使用示例

1. 屏幕宽度和高度适配

Container(
  padding: EdgeInsets.all(10.w), // 使用扩展方法
  width: 0.5.sw, // 屏幕宽度的50%
  height: 200.h, // 适应高度
  color: Colors.red,
  child: Text(
    'My actual width: ${0.5.sw}dp \n\nMy actual height: ${200.h}dp',
    style: TextStyle(color: Colors.white, fontSize: 12.sp),
  ),
)

2. 不使用扩展方法

Container(
  padding: EdgeInsets.all(ScreenUtil().setWidth(10)), // 使用原始方法
  width: ScreenUtil().setWidth(180), // 设计稿宽度180dp
  height: ScreenUtil().setHeight(200), // 设计稿高度200dp
  color: Colors.blue,
  child: Text(
    'My design draft width: 180dp\n\nMy design draft height: 200dp',
    style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12)),
  ),
)

3. 适配正方形

Container(
  padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
  width: 100.r, // 使用r表示宽度和高度都适配
  height: 100.r,
  color: Colors.green,
  child: Text(
    'I am a square with a side length of 100',
    style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12)),
  ),
)

4. 获取屏幕信息

Text('Device width:${ScreenUtil().screenWidth}dp'),
Text('Device height:${ScreenUtil().screenHeight}dp'),
Text('Device pixel density:${ScreenUtil().pixelRatio}'),
Text('Bottom safe zone distance:${ScreenUtil().bottomBarHeight}dp'),
Text('Status bar height:${ScreenUtil().statusBarHeight}dp'),
Text('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}'),
Text('The ratio of actual height to UI design:${ScreenUtil().scaleHeight}'),
Text('System font scaling factor:${ScreenUtil().textScaleFactor}'),

字体适配

1. 全局设置字体不随系统变化

MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Flutter_ScreenUtil',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  builder: (context, widget) {
    return MediaQuery(
      data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
      child: widget,
    );
  },
  home: HomePage(title: 'FlutterScreenUtil Demo'),
),

2. 单独设置字体不随系统变化

Text("text", textScaleFactor: 1.0)

扩展方法

从Dart SDK 2.6开始,插件提供了扩展方法,可以直接使用 .w, .h, .r, .sp 等快捷方式。

Container(
  width: 50.w, // 屏幕宽度的50%
  height: 200.h, // 屏幕高度的200px
)

示例代码

以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      designSize: Size(360, 690),
      builder: () => MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter_ScreenUtil',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          textTheme: TextTheme(button: TextStyle(fontSize: 45.sp)),
        ),
        home: HomePage(title: 'FlutterScreenUtil Demo'),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key key, this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Row(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.all(10.w),
                  width: 0.5.sw,
                  height: 200.h,
                  color: Colors.red,
                  child: Text(
                    'My actual width: ${0.5.sw}dp \n\nMy actual height: ${200.h}dp',
                    style: TextStyle(color: Colors.white, fontSize: 12.sp),
                  ),
                ),
                Container(
                  padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
                  width: ScreenUtil().setWidth(180),
                  height: ScreenUtil().setHeight(200),
                  color: Colors.blue,
                  child: Text(
                    'My design draft width: 180dp\n\nMy design draft height: 200dp',
                    style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12)),
                  ),
                ),
              ],
            ),
            Container(
              padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
              width: 100.r,
              height: 100.r,
              color: Colors.green,
              child: Text(
                'I am a square with a side length of 100',
                style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12)),
              ),
            ),
            Text('Device width:${ScreenUtil().screenWidth}dp'),
            Text('Device height:${ScreenUtil().screenHeight}dp'),
            Text('Device pixel density:${ScreenUtil().pixelRatio}'),
            Text('Bottom safe zone distance:${ScreenUtil().bottomBarHeight}dp'),
            Text('Status bar height:${ScreenUtil().statusBarHeight}dp'),
            Text('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}'),
            Text('The ratio of actual height to UI design:${ScreenUtil().scaleHeight}'),
            SizedBox(height: 10.h),
            Text('System font scaling factor:${ScreenUtil().textScaleFactor}'),
            SizedBox(height: 5),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  '16sp, will not change with the system.',
                  style: TextStyle(color: Colors.black, fontSize: 16.sp),
                  textScaleFactor: 1.0,
                ),
                Text(
                  '16sp, if data is not set in MediaQuery, my font size will change with the system.',
                  style: TextStyle(color: Colors.black, fontSize: 16.sp),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter屏幕适配插件flutter_screenfit的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter屏幕适配插件flutter_screenfit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_screenfit 是一个用于 Flutter 屏幕适配的插件,它可以帮助开发者在不同尺寸和分辨率的设备上实现一致的 UI 布局。使用 flutter_screenfit 可以避免手动计算屏幕尺寸和字体大小的繁琐操作。

安装

首先,你需要在 pubspec.yaml 文件中添加 flutter_screenfit 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_screenfit: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

初始化

在你的应用的 main.dart 文件中,初始化 flutter_screenfit

import 'package:flutter/material.dart';
import 'package:flutter_screenfit/flutter_screenfit.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Screenfit Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ScreenfitInit(
        designSize: Size(375, 812), // 设计稿的尺寸(例如 iPhone 11 的设计稿尺寸)
        child: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Screenfit Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello, World!',
              style: TextStyle(fontSize: 20.fit), // 使用 .fit 来适配字体大小
            ),
            Container(
              width: 100.fit, // 使用 .fit 来适配宽度
              height: 50.fit, // 使用 .fit 来适配高度
              color: Colors.blue,
            ),
          ],
        ),
      ),
    );
  }
}

使用 .fit 进行适配

flutter_screenfit 中,你可以使用 .fit 来对尺寸、边距、字体大小等进行适配。例如:

  • width: 100.fit:将宽度适配为当前设备的宽度比例。
  • height: 50.fit:将高度适配为当前设备的高度比例。
  • fontSize: 20.fit:将字体大小适配为当前设备的字体大小比例。

其他功能

flutter_screenfit 还提供了一些其他功能,例如:

  • ScreenfitUtil:可以通过 ScreenfitUtil 获取屏幕的宽度、高度、像素密度等信息。
  • ScreenfitInit:用于初始化 flutter_screenfit,并设置设计稿的尺寸。
double screenWidth = ScreenfitUtil.screenWidth;
double screenHeight = ScreenfitUtil.screenHeight;
double pixelRatio = ScreenfitUtil.pixelRatio;
回到顶部