Flutter全面屏适配

Stella981
• 阅读 847

笔者在这篇文章ReactNative全面屏(Android)适配问题提及了现在的全面屏问题,不仅是Android平台,IOS平台也是,给我的感觉就是手机越来越长了。 现在的手机长宽比早就不是之前的16:9了,比如iphoneX 的长宽比为13:6,而现在多数的Android手机都到了19.5:9,有的甚至达到了21:9。 基于科技的发展(适配的血泪史),Flutter开发自然也需要注意这个问题。 在Flutter开发中,通常使用Scaffold的appBar和bottomNavigationBar组件的页面是没有适配问题,它内部对全面屏进行了适配。 适配问题主要是出现在没有使用Scaffold的情况下。 看一下这段代码,没有使用Scaffold:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(    
        primarySwatch: Colors.blue,
      ),
    home: Container(
      color: Colors.white,
    child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        Container(
          color: Colors.lightBlue,
          child: Text('头部'),
        ),
        Container(
          color: Colors.redAccent,
          child: Text('底部'),
        )
      ],
    ),
    )
    );
  }
}

运行效果如下:

Flutter全面屏适配

可以看到上面和下面的组件已经被遮挡了,这就出现了适配问题,适配的主要问题就是集中在如下两点:

  1. 顶部的NavigationBar预留安全区域
  2. 底部的NavigationBar预留安全区域

对于以上两种问题,Flutter给出了除上面使用Scaffold,还有如下两种方案:

  1. 使用Flutter框架提供的SafeArea,Widget进行包裹组件来适配全面屏,这个组件和ReactNative框架中的SafeAreaView这个组件差不多效果,从两个名字就可以看出来,😀。
  2. 可以通过Flutter系统提供的MediaQuery.of(context).padding 这个Api来获取上下左右的安全padding,根据这个padding进行适配,更加灵活性。

接下来具体看一下这两个方案的使用

使用SafeArea适配

这个使用比较简单,只要需要将组件进行包裹即可,

home: SafeArea(child: Container(
      color: Colors.white,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Container(
            color: Colors.lightBlue,
            child: Text('头部'),
          ),
          Container(
            color: Colors.redAccent,
            child: Text('底部'),
          )
        ],
      ),
    ))

使用MediaQuery.of(context).padding适配

home位置修改为如下代码:
home: SafePage()
-------------------
创建一个SafePage
class SafePage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    EdgeInsets paddings = MediaQuery.of(context).padding;
    return Container(
        color: Colors.white,
        padding: EdgeInsets.fromLTRB(0, paddings.top, 0, paddings.bottom),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
              color: Colors.lightBlue,
              child: Text('头部'),
            ),
            Container(
              color: Colors.redAccent,
              child: Text('底部'),
            )
          ],
        ),
    );
  }
}

以上两种方案运行效果如下图,可以看到头部和底部已经正常显示了。 Flutter全面屏适配

上面这两种方案适用于IOS和Android两个平台,对于Android平台的适配在ReactNative全面屏(Android)适配问题也提到了另外的一种方案,看大家的实际需要,来采取合适的适配方案。

查看一下SafeArea这个Widget组件的源码,可以看到其实内部也是采用了上面提到的第二种方案,相当于SafeArea对第二种方案的封装,开发中使用起来更方便一下,源码如下

@override
  Widget build(BuildContext context) {
    assert(debugCheckHasMediaQuery(context));
    /// 如下五行代码就是SafeArea可以进行适配的原因,
    final MediaQueryData data = MediaQuery.of(context);
    EdgeInsets padding = data.padding;
    // Bottom padding has been consumed - i.e. by the keyboard
    if (data.padding.bottom == 0.0 && data.viewInsets.bottom != 0.0 && maintainBottomViewPadding)
      padding = padding.copyWith(bottom: data.viewPadding.bottom);

    return Padding(
      padding: EdgeInsets.only(
        left: math.max(left ? padding.left : 0.0, minimum.left),
        top: math.max(top ? padding.top : 0.0, minimum.top),
        right: math.max(right ? padding.right : 0.0, minimum.right),
        bottom: math.max(bottom ? padding.bottom : 0.0, minimum.bottom),
      ),
      child: MediaQuery.removePadding(
        context: context,
        removeLeft: left,
        removeTop: top,
        removeRight: right,
        removeBottom: bottom,
        child: child,
      ),
    );
  }

截图可能看起来更方便,注意看红框部分 Flutter全面屏适配

关于Flutter的全面屏适配先分享这些。

欢迎关注我的公众号:君伟说。分享移动开发技术,职场生活和工作中的酸甜苦辣。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Unity横屏
Android下发现Unity里面的Player设置,并不能完全有效,比如打开了自动旋转,启动的时候还是会横屏,修改XML添加以下代码<applicationandroid:icon"@drawable/ic\_launcher"                    android:label"@string/app\_name"
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这