ScrollView 与 SliverPadding 的关系

基本页面布局

Scaffold 中有个 ListView,ListView 中有 100 个高 50 的 Container 用作辅助观看,ListView 中第三个元素是一个 GridView,GridView 的滑动效果被禁止。

class GiveView extends GetView<GiveController> {
  const GiveView({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GiveView'),
        centerTitle: true,
      ),
      body: ListView.builder(
        itemCount: 100,
        itemBuilder: (context, index) {
          if (index == 3) {
            return SizedBox(
              height: 220,
              child: GridView.builder(
                itemCount: 10,
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 5,
                  mainAxisExtent: 100,
                  crossAxisSpacing: 20,
                  mainAxisSpacing: 20,
                ),
                itemBuilder: (BuildContext context, int index) {
                  return Image.network(
                      'https://img.xjh.me/random_img.php?return=302&time=${DateTime.now().microsecond}');
                },
              ),
            );
          }
          return Container(
            margin: const EdgeInsets.symmetric(vertical: 5),
            height: 50,
            decoration: BoxDecoration(
              border: Border.all(),
              color: Colors.amber,
            ),
          );
        },
      ),
    );
  }
}

如上图所示,要探究的问题就以此为基础。

与 AppBar 的关系

目前为止,页面布局看着都很正常,没有问题。

去掉 AppBar

有时候是不需要 AppBar 的,比如:

去掉之后变成了如下摸样,明显不符合预期,上边的状态栏、刘海都空白了,没有完全占满。就好像 ListView 与最上边有了一个状态栏高度的距离,至于是 Margin,还是 Padding,又或者是一个空的 Container,继续向下查看。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过查看 ListView 源码发现,在 packages/flutter/lib/src/widgets/scroll_view.dart:807 处发现会获取当前上下文的 mediaQuery 对象,并使用其中的 Padding。

ScrollView(ListView、GridView、BoxScrollView 的抽象类),在 build 时,会调用 buildSlivers,先看自身有没有设置 padding,如果设置了,那就用自己的。没设置就看 Widget 树中,最近的一个 MediaQuery 它的 padding 信息,以其为主。

找到了对应的代码逻辑,可以通过 Debug 和 DevTools 进行确认一下。

Debug 查看:

DevTools 查看:

由此也能看出,离 ListView 最近的一个 MediaQuery,其 Padding top 是 59,也就是状态栏的高度。

加上 AppBar

上面看到了去掉 AppBar 的情况,为了相互印证,把 AppBar 再加上进行查看。

Debug 查看:

DevTools 查看:

解决去掉 AppBar 的问题

方案 1

通过刚才的分析,现在已经很明白了,只需要给自己的 ScrollView 设置上 padding 即可,他就不会进入下面的代码:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终代码:

效果:

完美,咦,不对,怎么中间的 GridView 的布局不对劲了?看着应该是离上边有个状态栏高度的 padding,真是“拆了东墙补西墙”。细细想想,把 ListView 的 padding 设置上了,它用自己的 padding 了,可是 GridView 也是 ScrollView 的实现,所以它也会走这块代码:

方案 2

GridView 可没有给他设置 padding,所以它还是用 Scaffold 下、GridView 上(Widget 树中)的那个 MediaQuery 中的 padding 信息,所以还是有个 top: 59 的距离,简单做法就是给 GridView 也设置上他自己的 padding,可是我已经烦了,难道每多一个 ScrollView 就要给他设置个 padding?

既然知道是 ScrollView 最近的 MediaQuery 导致的,那可以不可以一劳永逸,把这个最近的 MediaQuery 换了?当然可以,这里在 ListView 外边加一个自己的 MediaQuery:

Widget build(BuildContext context) {
  return Scaffold(
    // 手动增加一层 MediaQuery,默认的 padding 为 0
    body: MediaQuery(
      data: const MediaQueryData(),
      child: ListView.builder(
        itemCount: 100,
        itemBuilder: (context, index) {
          if (index == 3) {
            return SizedBox(
              height: 220,
              child: GridView.builder(
                physics: const NeverScrollableScrollPhysics(),
                itemCount: 10,
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 5,
                  mainAxisExtent: 100,
                  crossAxisSpacing: 20,
                  mainAxisSpacing: 20,
                ),
                itemBuilder: (BuildContext context, int index) {
                  return Image.network(
                      'https://img.xjh.me/random_img.php?return=302&time=${DateTime.now().microsecond}');
                },
              ),
            );
          }
          return Container(
            margin: const EdgeInsets.symmetric(vertical: 5),
            height: 50,
            decoration: BoxDecoration(
              border: Border.all(),
              color: Colors.amber,
            ),
          );
        },
      ),
    ),
  );
}

这样在 Scaffold 下、ListView 上就是自己创建的这个 MediaQuery 了。

还有另一种方式是使用 MediaQuery.removePadding 是一样的道理。

外部 ScrollView 使用 padding 与不使用的区别

恢复到自己插入 MediaQuery 之前的代码:

Widget build(BuildContext context) {
  return Scaffold(
    body: ListView.builder(
      itemCount: 100,
      itemBuilder: (context, index) {
        if (index == 3) {
          return SizedBox(
            height: 220,
            child: GridView.builder(
              physics: const NeverScrollableScrollPhysics(),
              itemCount: 10,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 5,
                mainAxisExtent: 100,
                crossAxisSpacing: 20,
                mainAxisSpacing: 20,
              ),
              itemBuilder: (BuildContext context, int index) {
                return Image.network(
                    'https://img.xjh.me/random_img.php?return=302&time=${DateTime.now().microsecond}');
              },
            ),
          );
        }
        return Container(
          margin: const EdgeInsets.symmetric(vertical: 5),
          height: 50,
          decoration: BoxDecoration(
            border: Border.all(),
            color: Colors.amber,
          ),
        );
      },
    ),
  );
}

给 ListView 加上 padding:

这两个的区别就在于 ListView 加不加 padding。

  • 没加:内部的 ScrollView 布局正常。
  • 加了:内部的 ScrollView 布局异常,有一个高度为状态栏高度的 top padding。

那来分析分析原因,还得回到 ScrollView 的 buildSlivers 中(packages/flutter/lib/src/widgets/scroll_view.dart:803)。

前者

先说前者,ListView 没有设置 padding,所以会执行红框范围的代码,其中 819 行包裹了一层 MediaQuery,这就和上边自行加一层 MediaQuery 的效果是一样的了,后续在 ListView 中的 ScrollView 都将默认使用此 MediaQuery,所以布局没有问题。

后者

后者,由于 ListView 设置有 padding,就不会走红框范围的代码,那也就不会在 Widget 树中增加一个 MediaQuery,所以在 ListView 内部的 ScrollView 如果自己不设置 padding,还是会使用那个 padding top = 59 的 MediaQuery。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/132300.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity之UI编程】编写一个面板交互界面需要注意的细节

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

【Java】基于SpringBoot创建Web页面并热更新

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍基于SpringBoot创建Web页面并热更新。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

低价寄快递寄件微信小程序 实际商用版,对接了低价快递渠道,运营平台赚取差价,支持市面上全部主流快递

盈利模式 快递代下CPS就是用户通过线上的渠道&#xff08;快递小程序&#xff09;&#xff0c;线上下单寄快递来赚取差价&#xff0c;例如你的成本价是5元&#xff0c;你在后台比例设置里面设置 首重利润是1元&#xff0c;续重0.5元&#xff0c;用户下1kg的单页面显示的就是6元…

前端和空字符串、零比较时请务必使用===

在前端开发中遇到一个问题&#xff0c;以下两条语句的结果都是true。 console.log(0 ""); console.log(false ""); 这就导致了editingId为0的时候&#xff0c;if分支并没有执行&#xff0c;而我的本意是当editingId不是空也不是空字符串的时候执行分支…

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache&#xff08;JSR-107&#xff09;注解简化我们的开发。&#xfeff; 其…

Unity中Shader的间接光的产生Meta Pass

文章目录 前言Unity中Shader的间接光的产生Meta Pass&#xff0c;这也是属于全局光照 GI 的内容。主要实现像现实生活中&#xff0c;光线照到有颜色的物体后&#xff0c;该物体有反射出该颜色的光的效果。 一、我们先使用Unity自带的Shader看看间接光效果1、先按照如下设置搭建…

数字滤波器设计---FIR 滤波器设计

数字滤波器设计---FIR 滤波器设计 FIR 滤波器与 IIR 滤波器的比较 与无限持续时间冲激响应 (IIR) 滤波器相比&#xff0c;具有有限持续时间冲激响应的数字滤波器&#xff08;全零或 FIR 滤波器&#xff09;既有优点又有缺点。 FIR 滤波器具有以下主要优点&#xff1a; 它们可…

关于Android Studio 同步Gradle失败的解决方案

&#xff08;1&#xff09;打开Android Studio的Settings找到Gradle的目录 &#xff08;2&#xff09;打开本地文件目录&#xff0c;找到对应的gradle版本&#xff0c;可以通过Index of /gradle/ 下载gradle压缩包。把目录中gradle-7.0.2-bin\一堆字符\ 下 的.lck 和.part文…

数据管理系统-week1-文件系统、数据库和数据库管理系统

文章目录 前言一、 文件系统文件系统的限制 二、 数据库系统三、 数据库管理系统参考文献 前言 一、 文件系统 对于更高级的数据处理应用程序来说&#xff0c;基于数据块的持久存储逻辑模型过于简单数据块序列被划分为称为文件的数据块的可变子序列&#xff0c;与文件相关的名…

香港云服务器用于跨境电商外贸

港作为国际金融中心和互联网枢纽&#xff0c;具有非常发达的网络基础设施和优质的网络连接。这意味着在香港租用云服务器&#xff0c;外贸企业可以享受到高速稳定的网络连接&#xff0c;确保数据传输的安全和稳定性。这对于外贸企业来说至关重要&#xff0c;因为他们需要频繁地…

html+css+javascript打造网页内容浮动导航菜单

1需求分析 前段时间把“圳品”信息发布到网站上了&#xff0c;内容包括四大块&#xff1a; 按分布区域统计分析按产品类别统计分析按认定时间统计分析河池市“圳品”清单 导致网页很长&#xff0c;有同事反映说查看起来不是很方便&#xff0c;于是决定加上一个网页内容浮动导…

视通科技新品发布:4K30分布式编解码一体机,高性价比之选!

随着信息技术的日新月异&#xff0c;各领域对于音视频传输、控制和显示等方面的需求呈现出爆发式的增长。这种需求的增长源于多种因素&#xff0c;包括但不限于高清视频的普及&#xff0c;实时音视频通信的广泛应用&#xff0c;以及各种显示设备的升级换代。 在这样的背景下&a…

大数据治理——为业务提供持续的、可度量的价值(一)

目录 大数据治理——为业务提供持续的、可度量的价值... 1 概述... 2 大数据治理系列... 2 第一部分&#xff1a;大数据治理统一流程模型概述和明确元数据管理策略... 2 第二部分&#xff1a;元数据集成体系结构... 15 第三部分&#xff1a;实施元数据管理... 25 第四部…

基于ubuntu22.04手动安装openstack——2023.2版本(最新版)的问题汇总

前言&#xff1a;基本上按照openstack官方网站动手可以搭建成功&#xff08;如有需要私信发部署文档&#xff09;。 但是任然有些小问题&#xff0c;所以汇总如下。 第一个问题 问题&#xff1a; ubuntu搭建2023.2版本neutorn报错&#xff0c;ERROR neutron.plugins.ml2.driv…

传奇GOM引擎微端连接不上如何解决

Gom传奇引擎的微端连不上的原因可能有很多&#xff0c;比如网络问题、服务器配置问题、版本兼容性问题等。1.检查网络连接&#xff1a;首先要确保你的网络连接稳定。如果遇到网络问题&#xff0c;比如网络延迟过高&#xff0c;可能会导致你无法连接到服务器。建议使用稳定的网络…

Linux-基础知识

1.快捷键 ctrlc 强制停止 ctrld 退出或登出 history 查看历史命令&#xff08;&#xff01;/ctrlr输入内容去匹配历史命令&#xff09; 光标移动快捷键 ctrla,跳到命令开头 ctrle,跳到命令结尾 ctrl键盘左键&#xff0c;向左跳一个单词 ctrl键盘右键&…

Maven打包引入本地依赖包

Maven打包引入本地依赖包 SpringBoot 工程&#xff0c;Maven 在构建项目时&#xff0c;如何引入本地 Jar 包&#xff1f; 适合场景&#xff1a; 引用的依赖不在 Maven 仓库第三方公司提供的 SDK 包Maven 内网离线开发引入被定制改动过的 Jar 包 解决方法&#xff1a; 在 I…

数据分析实战 | KNN算法——病例自动诊断分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 九、模型调参 十、模型改进 十一、模型预测 一、数据及分析对象 CSV文件——“bc_data.csv” 数据集链接&#xff1a;https://dow…

共享变量可见性问题以及解决方案

文章目录 1. 简介2. 解决方案 1. 简介 首先在了解可见性问题之前我们首先需要给出Java 内存模型的定义&#xff08;JMM&#xff09;&#xff0c;java讲内存模型抽象为两个部分&#xff0c;主存以及工作内存&#xff0c;主 存也就是所有线程所共享的一段存储空间&#xff0c;工…

Netty--NIO(Non-blocking IO)基础--三大组件

NIO&#xff08;Non-blocking IO&#xff09;是一种非阻塞的IO模型&#xff0c;它通过引入Channel和Selector的概念&#xff0c;使得一个线程能够管理多个通道&#xff0c;从而提高了IO操作的效率。本文将介绍NIO的三大组件&#xff1a;Channel、Buffer、以及Selector&#xff…