flutter屏幕适配方案

发布时间 2023-12-18 17:48:35作者: 鲤斌

使用MediaQuery和比例因子

优点:使用简单,可以处理大多数情况下的屏幕适配需求。

缺点:需要手动计算比例因子,并且随着UI元素变得更加复杂和层次化(例如多层次列表或动画效果),使用此方法可能会变得更加困难。

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 使用 MediaQuery.of(context) 获取 MediaQueryData 对象
    final mediaQueryData = MediaQuery.of(context);

    // 获取屏幕大小
    final screenSize = mediaQueryData.size;

    // 获取设备像素比
    final devicePixelRatio = mediaQueryData.devicePixelRatio;

    // 获取 SafeArea 内边距 ; SafeArea 是一个指定在屏幕上可见内容的区域
    final padding = mediaQueryData.padding;

    // 获取当前可见区域的内边距
    final viewInsets = mediaQueryData.viewInsets;

    // 获取屏幕方向
    final orientation = mediaQueryData.orientation;

    // 获取平台亮度模式
    final brightness = mediaQueryData.platformBrightness;

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MediaQuery Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('Screen Size: $screenSize'),
              Text('Device Pixel Ratio: $devicePixelRatio'),
              Text('SafeArea Padding: $padding'),
              Text('View Insets: $viewInsets'),
              Text('Orientation: $orientation'),
              Text('Brightness: $brightness'),
            ],
          ),
        ),
      ),
    );
  }
}

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

flutter_screenutil

优点:使用简单,支持屏幕宽度适配和按照设备像素密度适配,并提供了多种适配方式,可以应对多种屏幕尺寸和设备像素密度的情况。

缺点:在高级UI布局和元素调整方面可能存在一些限制,并可能会影响代码的可维护性。

flutter_screenutil 插件的 ScreenUtilInit 对 MaterialApp 进行了包装,以便于在应用程序启动时对屏幕适配进行初始化。然而,由于这个包装可能会与某些特定应用场景的组件结合使用,导致一些额外的问题。一般来说,flutter_screenutil 可能会给您带来以下一些问题:

  1. 在一些特定应用场景下可能会失效:例如,在 BottomNavigationBar 或者 TabBar 中,因为这些组件自带屏幕适配,使用 flutter_screenutil 可能会导致无法正常适配。

  2. 需要注意不同尺寸之间的兼容性:使用 flutter_screenutil 后,您需要确保您的应用程序可以在不同的尺寸上正常工作,否则可能会导致布局问题。

  3. 可能会对性能造成一定的影响:由于 flutter_screenutil 需要在运行时进行适配计算,可能会对应用程序的性能造成一定的影响。

  4. debugShowCheckedModeBanner :false;失效
import 'package:flutter_screenutil/flutter_screenutil.dart';  //使用的页面都要添加

void main() {
  runApp(
    MaterialApp(
        debugShowCheckedModeBanner: false, // 在这添加可以解决debugShowCheckedModeBanner失效问题
      home: ScreenUtilInit(
        designSize: const Size(1920, 1080), //第一个参数是宽度,第二个参数是高度
        builder: (context, widget) =>  MyApp(),
        
      ),
    ),
  );
}

// 屏幕宽度(单位 dp)
double screenWidth = ScreenUtil().screenWidth;

// 屏幕高度
double screenHeight = ScreenUtil().screenHeight;

// 根据屏幕宽度动态计算出的实际宽度
double width = ScreenUtil().setWidth(200);

// 根据屏幕高度动态计算出的实际高度
double height = ScreenUtil().setHeight(200);

// 根据屏幕宽度和高度动态计算出的实际字体大小
double fontSize = ScreenUtil().setSp(18);

LayoutBuilder 来获取一个内的盒子的宽度和高度

class MyBoxWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        double width = constraints.maxWidth;
        double height = constraints.maxHeight;

        return Container(
          color: Colors.blue,
          width: width,
          height: height,
          child: Text(
            'Width: $width, Height: $height',
            style: TextStyle(color: Colors.white),
          ),
        );
      },
    );
  }
}

...