Flutter组件适配方法实现详解

 更新时间:2022年10月31日 15:20:20   作者:A 曦曦  
在写flutter的代码的时候为了让组件大小适配屏幕使用了flutter_screenUtil插件。在调试的时候是正常的,可以适配屏幕。但是打包之后就会失去效果,这篇文章主要介绍了Flutter组件适配方法实现

Flutter 适配组件

在 Flutter 我们只需要掌握一些 Widget 即可,实际的开发过程中,我们也只需要在合适的地方使用它们即可。

1. MediaQuery

第一个 Widget 即是 MediaQuery,通过它可以直接获得屏幕的大小(宽度 / 高度)和方向(纵向 / 横向)。

cclass HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;
    Orientation orientation = MediaQuery.of(context).orientation;
    return Scaffold(
      body: Container(
        color: CustomColors.android,
        child: Center(
          child: Text(
            'View\n\n' +
                '[MediaQuery width]: ${screenSize.width.toStringAsFixed(2)}\n\n' +
                '[MediaQuery orientation]: $orientation',
            style: TextStyle(color: Colors.white, fontSize: 18),
          ),
        ),
      ),
    );
  }
}

2. LayoutBuilder

使用 LayoutBuilder 组件,可以获得一个 BoxConstraints 对象,通过该对象我们就可以拿到 Widget 的 maxWidth(最大宽度) 和maxHeight(最大高度)

MediaQuery 和 LayoutBuilder 的区别在在于,MediaQuery 得到的是整个屏幕的宽高,而 LayoutBuilder 得到的是特定组件的最大高度和宽度。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;
    return Scaffold(
      body: Row(
        children: [
          Expanded(
            flex: 2,
            child: LayoutBuilder(
              builder: (context, constraints) => Container(
                color: CustomColors.android,
                child: Center(
                  child: Text(
                    'View 1\n\n' +
                        '[MediaQuery]:\n ${screenSize.width.toStringAsFixed(2)}\n\n' +
                        '[LayoutBuilder]:\n${constraints.maxWidth.toStringAsFixed(2)}',
                    style: TextStyle(color: Colors.white, fontSize: 18),
                  ),
                ),
              ),
            ),
          ),
          Expanded(
            flex: 3,
            child: LayoutBuilder(
              builder: (context, constraints) => Container(
                color: Colors.white,
                child: Center(
                  child: Text(
                    'View 2\n\n' +
                        '[MediaQuery]:\n ${screenSize.width.toStringAsFixed(2)}\n\n' +
                        '[LayoutBuilder]:\n${constraints.maxWidth.toStringAsFixed(2)}',
                    style: TextStyle(color: CustomColors.android, fontSize: 18),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

3. OrientationBuilder

要确定当前 Widget 的方向,可以使用 OrientationBuilder 组件。这里的方向与 MediaQuery 提供的设备方向不同。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Orientation deviceOrientation = MediaQuery.of(context).orientation;
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            flex: 2,
            child: Container(
              color: CustomColors.android,
              child: OrientationBuilder(
                builder: (context, orientation) => Center(
                  child: Text(
                    'View 1\n\n' +
                        '[MediaQuery orientation]:\n$deviceOrientation\n\n' +
                        '[OrientationBuilder]:\n$orientation',
                    style: TextStyle(color: Colors.white, fontSize: 18),
                  ),
                ),
              ),
            ),
          ),
          Expanded(
            flex: 3,
            child: OrientationBuilder(
              builder: (context, orientation) => Container(
                color: Colors.white,
                child: Center(
                  child: Text(
                    'View 2\n\n' +
                        '[MediaQuery orientation]:\n$deviceOrientation\n\n' +
                        '[OrientationBuilder]:\n$orientation',
                    style: TextStyle(color: CustomColors.android, fontSize: 18),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

4. Expanded 和 Flexible

Expanded 和 Flexible 这两个组件可以和 Column/Row 搭配使用,来实现非常完美的自适应效果。Expanded 可以用来拓展 Row, 、Column 和 Flex,从而让子组件填充可用空间,Flexible 功能类似但并不一定能填充全部可用空间。

下面这个例子演示了混合使用 Expanded 和 Flexible 的各种方式:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Column(
          children: [
            Row(
              children: [
                ExpandedWidget(),
                FlexibleWidget(),
              ],
            ),
            Row(
              children: [
                ExpandedWidget(),
                ExpandedWidget(),
              ],
            ),
            Row(
              children: [
                FlexibleWidget(),
                FlexibleWidget(),
              ],
            ),
            Row(
              children: [
                FlexibleWidget(),
                ExpandedWidget(),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
class ExpandedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        decoration: BoxDecoration(
          color: CustomColors.android,
          border: Border.all(color: Colors.white),
        ),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text(
            'Expanded',
            style: TextStyle(color: Colors.white, fontSize: 24),
          ),
        ),
      ),
    );
  }
}
class FlexibleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Flexible(
      child: Container(
        decoration: BoxDecoration(
          color: CustomColors.androidAccent,
          border: Border.all(color: Colors.white),
        ),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text(
            'Flexible',
            style: TextStyle(color: CustomColors.android, fontSize: 24),
          ),
        ),
      ),
    );
  }
}

5. FractionallySizedBox

FractionallySizedBox 组件可以使子组件填充部分可用空间,该特性在 Expanded 或 Flexible 中特别有用。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FractionallySizedWidget(widthFactor: 0.4),
              ],
            ),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FractionallySizedWidget(widthFactor: 0.6),
              ],
            ),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FractionallySizedWidget(widthFactor: 0.8),
              ],
            ),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FractionallySizedWidget(widthFactor: 1.0),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
class FractionallySizedWidget extends StatelessWidget {
  final double widthFactor;
  FractionallySizedWidget({@required this.widthFactor});
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: FractionallySizedBox(
        alignment: Alignment.centerLeft,
        widthFactor: widthFactor,
        child: Container(
          decoration: BoxDecoration(
            color: CustomColors.android,
            border: Border.all(color: Colors.white),
          ),
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Text(
              '${widthFactor * 100}%',
              style: TextStyle(color: Colors.white, fontSize: 24),
            ),
          ),
        ),
      ),
    );
  }
}

6. AspectRatio

AspectRatio 组件可以直接指定子组件的固定宽高比例,使用时,我们可以使用布局约束的最大宽度,并给定一个宽高比自适应其高度

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Column(
          children: [
            AspectRatioWidget(ratio: '16 / 9'),
            AspectRatioWidget(ratio: '3 / 2'),
          ],
        ),
      ),
    );
  }
}
class AspectRatioWidget extends StatelessWidget {
  final String ratio;
  AspectRatioWidget({@required this.ratio});
  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: Fraction.fromString(ratio).toDouble(),
      child: Container(
        decoration: BoxDecoration(
          color: CustomColors.android,
          border: Border.all(color: Colors.white),
        ),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Center(
            child: Text(
              'AspectRatio - $ratio',
              style: TextStyle(color: Colors.white, fontSize: 24),
            ),
          ),
        ),
      ),
    );
  }
}

到此这篇关于Flutter组件适配方法实现详解的文章就介绍到这了,更多相关Flutter组件适配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android自定义左右或上下滑动翻页效果

    Android自定义左右或上下滑动翻页效果

    这篇文章主要为大家详细介绍了Android自定义左右或上下滑动翻页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • android之ContentResolver与ContentProvider介绍

    android之ContentResolver与ContentProvider介绍

    这篇文章主要介绍了android之ContentResolver与ContentProvider介绍,需要的朋友可以参考下
    2016-01-01
  • Android自定义圆角ImageView

    Android自定义圆角ImageView

    这篇文章主要介绍了Android自定义圆角ImageView的相关资料,需要的朋友可以参考下
    2016-01-01
  • Android侧滑效果简单实现代码

    Android侧滑效果简单实现代码

    这篇文章主要为大家详细介绍了Android侧滑效果简单实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android手机屏幕敲击解锁功能代码

    Android手机屏幕敲击解锁功能代码

    Android手机支持敲击屏幕解锁,敲击屏幕解锁是一项很实用的功能,本文以android平台为例使用java代码实现Android手机屏幕敲击解锁功能,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-07-07
  • 解决Android Studio一直停留在MyApplication:syncing的问题

    解决Android Studio一直停留在MyApplication:syncing的问题

    这篇文章主要介绍了Android Studio一直停留在MyApplication:syncing的完美解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Android实现桌面悬浮小火箭效果

    Android实现桌面悬浮小火箭效果

    这篇文章主要为大家详细介绍了Android实现桌面悬浮小火箭效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Android编程记录ListView标记行状态的方法

    Android编程记录ListView标记行状态的方法

    这篇文章主要介绍了Android编程记录ListView标记行状态的方法,结合实例分析了ListView标记的相关实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Android利用Senser实现不同的传感器

    Android利用Senser实现不同的传感器

    这篇文章主要为大家详细介绍了Android利用Senser实现不同传感器的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • Android Mms之:深入理解Compose

    Android Mms之:深入理解Compose

    本篇文章是对Compose进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论