当前位置: 首页 > news >正文

Flutter问题记录 - 布局中莫名其妙的白线/缝隙

文章目录

  • 前言
  • 开发环境
  • 问题描述
  • 问题分析
  • 解决方案
  • 最后


前言

最近客服反馈了一个奇怪的问题,有个用户反馈其他问题时给了应用截图,然后他发现这截图中有一条奇怪的白线。他在自己手机上没有发现这个问题,于是提工单反馈到我这。

开发环境

  • Flutter: 3.24.3

问题描述

应用截图原图没办法给出,白线大概长这样(不是很明显,图片上传被压缩后可能更不明显):

screenshot1

白线分割的上下两部分,分别是两个Container组件。

问题分析

首先这个问题在公司一堆测试机中都没有发现,查了该用户的登录设备型号是:Xiaomi 23116PN5BC,也就是小米14 Pro

找同型号的云真机测试一番,确实存在这个问题,但是在其他很多手机上都没有发现这个问题,初步判断应该是跟设备屏幕分辨率有关。小米14 Pro分辨率信息如下:

物理分辨率:1440x3200
逻辑分辨率:411x898
设备像素比(devicePixelRatio):2.625

物理分辨率是网上查的,其他的通过Flutter获取。奇怪,devicePixelRatio好像不太对,有点太小了。一般来说:

物理分辨率 = 逻辑分辨率 * 设备像素比

411 * 2.625 = 1078.875,这相差的有点多,这设备像素比更像是小米 14(物理分辨率:1080x2400)的。

这设备像素比合不合理另说,先找一个逻辑分辨率和设备像素比差不多的模拟器用于本地跑demo测试,同时也可以进一步验证这个问题是不是只在小米14 Pro上出现。

这个网站可以查看iPhone/Pixel/Galaxy的大部分设备分辨率信息,找到一个比较符合要求的Google Pixel 7

screenshot2

直接新建一个Google Pixel 7模拟器,再写个测试用的demo:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Flutter问题记录 - 布局中莫名其妙的白线/缝隙',style: TextStyle(fontSize: 18),),),body: SingleChildScrollView(child: Column(children: [Container(color: Colors.purple,height: 100,),Container(color: Colors.purple,height: 100,),],),),),);}
}

运行后白线出现了,截图请看前面的问题描述。现在可以确定这问题不局限于小米14 Pro,再仔细看截图中的白线高度明显小于1个逻辑像素,基本可以判断这是由于逻辑像素转为设备像素后出现小数取整导致的问题,毕竟物理像素不能是小数。

实测将第一个Container的高度从100逐渐增加到104,白线的粗细会不断变化,直到104时白线消失。这应该和Flutter的取整方式以及抗锯齿处理有关,由于组件边缘像素对齐误差的变化,被渲染为背景色的区域大小也在不断变化,从而造成粗细不一的白线(如果背景色是白色的)。

100 * 2.625 = 262.5
101 * 2.625 = 265.125
102 * 2.625 = 267.75
103 * 2.625 = 270.375
104 * 2.625 = 273

那该怎么解决这个问题呢?最简单的方法:

View.of(context).devicePixelRatio == 2.625 ? 104 : 100;

根据设备像素比返回不同的逻辑像素,避免得到的物理像素是小数。虽然看上去有点不靠谱,但是简单有效,毕竟这个问题也不是那么容易遇到的,它需要满足以下条件:

  • 两个背景颜色相同的组件放在一起,颜色不同基本发现不了
  • 设备像素比是2.625这种,像iPhone设备像素比全是整数根本不会出现该问题,大部分Android设备也不会出现。开发时逻辑像素尽量使用偶数,这样就算设备像素比是3.5的Android设备得到的物理像素也基本是整数

当然,也有更靠谱一点的解决方式:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Flutter问题记录 - 布局中莫名其妙的白线/缝隙',style: TextStyle(fontSize: 18),),),body: SingleChildScrollView(child: Column(children: [Container(// color: Colors.purple,height: 100,decoration: BoxDecoration(color: Colors.purple,border: Border.all(width: 0,color: Colors.purple,),),),Container(// color: Colors.purple,height: 100,decoration: BoxDecoration(color: Colors.purple,border: Border.all(width: 0,color: Colors.purple,),),),],),),),);}
}

设置宽度为0的边框起到像素对齐的作用。注意,都需要设置,不然很可能还会有白线。

这问题也不是什么新鲜问题,目前也没有完美的解决方案,相关的issue很多,例如:Antialiasing behaviour when same-colour。

解决方案

  1. 对特定设备像素比适配,参考如下:
View.of(context).devicePixelRatio == 2.625 ? 104 : 100;
  1. 给组件设置宽度为0的边框,参考如下:
Container(// color: Colors.purple,height: 100,decoration: BoxDecoration(color: Colors.purple,border: Border.all(width: 0,color: Colors.purple,),),
)

最后

如果这篇文章对你有所帮助,点赞👍收藏🌟支持一下吧,谢谢~


本篇文章由@crasowas发布于CSDN。

相关文章:

Flutter问题记录 - 布局中莫名其妙的白线/缝隙

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 最近客服反馈了一个奇怪的问题,有个用户反馈其他问题时给了应用截图,然后他发现这截图中有一条奇怪的白线。他在自己手机上没有发现这个问题,于是提工单反馈到我这。 开发环境 Fl…...

从零学习大模型(七)-----LoRA(中)

自注意力层中的 LoRA 应用 Transformer 的自注意力机制是模型理解输入序列之间复杂关系的核心部分。自注意力层通常包含多个线性变换,包括键(Key)、查询(Query) 和 值(Value) 三个权重矩阵的线…...

Java知识巩固(十二)

I/O JavaIO流了解吗? IO 即 Input/Output,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因…...

一家光伏企业终止,恐不具行业代表性,市占率仅为2.35%

海达光能终止原因如下:报告期内海达光能销售金额较所在行业第二名亚玛顿相差两倍以上,公司毛利率更是远低于行业龙头福莱特,恐难以说明公司行业代表性。在企业竞争上,公司2021年度的市场占有率约为2.35%,公司未来光伏玻…...

企业计算机监控软件是什么?6款电脑监控软件分享!提升企业管理效率,吐血推荐!

嘿,各位企业管理者和IT小伙伴们! 您是否曾担忧员工在工作时间内效率低下?是否对公司的数据安全感到不安? 别担心,今天我们就来聊聊企业计算机监控软件,它就像是企业的"超级侦探",帮…...

VisionPro —— CogOCRMaxTool工具详解

CogOCRMaxTool的作用: CogOCRMaxTool:是一个字符识别工具,主要用于字符识别,它能够根据已训练的字符样本读取灰度图像中的字符,并返回读取结果。 一:工具位置 二:添加图片 三:工具的初始页面 将识别框拖到需要识别处…...

网站安全问题都有哪些,分别详细说明

网站安全问题涉及多个方面,以下是一些常见的网站安全问题及其详细说明: 数据泄露 问题描述:数据泄露是指网站存储的用户敏感信息(如用户名、密码、信用卡信息等)被非法获取。黑客可能通过SQL注入、XSS攻击等手段窃取这…...

DiskGenius一键修复磁盘损坏

下午外接磁盘和U盘都出现扇区损坏,估计就是在开着电脑,可能是电脑运行的软件还在对磁盘进行读写,不小心按到笔记本关机键,重新开机读写磁盘分区变得异常卡顿,估摸就是这个原因导致扇区损坏。在进行读写时,整…...

Matlab实现鼠群优化算法优化回声状态网络模型 (ROS-ESN)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 鼠群优化算法(Rat Swarm Optimization, ROS)是一种基于老鼠群体行为的群体智能优化算法。ROS通过模拟老鼠在寻找食物时的聚集、分散和跟随行为,来探索解空间并寻找最优解。该算…...

nfs作业

一、作业要求 1、开放/nfs/shared目录,供所有用户查询资料 2、开放/nfs/upload目录,为192.168.xxx.0/24网段主机可以上传目录, 并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210 3、将/home/tom目录仅共享给192.168.xxx.xxx这台…...

Linux 基础io_理解文件系统_软硬链接_动静态库

一.磁盘 1.磁盘物理结构 盘片 磁盘可以有多个磁片,每个磁片有两个盘面,每个盘面都对应一个磁头,都可以存储数据。 磁道 扇区 磁道是指在盘面上,由磁头读写的数据环形轨道。每个磁道都是由一圈圈的圆形区域组成,数据…...

大语言模型参数传递、model 构建与tokenizer构建(基于llama3模型)

文章目录 前言一、传递参数构建1、构建模型参数2、构建数据参数3、构建训练参数4、类似parse方式解析数据、模型、训练参数五、构建tokenizer与model1、tokenizer与model调用代码2、tokenizer实现2、model实现前言 上一篇说到huggingface的参数传递理论方法,本篇文章应用与ll…...

使用 `screen` + `nohup` 实现高效日志记录和多环境任务管理

使用 screen nohup 实现高效日志记录和多环境任务管理 在深度学习模型训练中,特别是在服务器上运行长时间的任务时,有效的任务管理和日志记录至关重要。我们通常需要在后台运行多个任务,同时为每个任务配置不同的 conda 环境。通过结合使用…...

【探索数字孪生,引领未来技术】

在数字化浪潮的推动下,数字孪生技术正成为连接虚拟与现实的桥梁,它不仅是工业互联网的基石,更是智慧城市、智慧园区、智慧楼宇以及元宇宙构建的核心。为了帮助更多专业人士掌握这一前沿技术,我们荣幸地宣布,“新质技术…...

Tcp_Sever(线程池版本的 TCP 服务器)

Tcp_Sever(线程池版本的 TCP 服务器) 前言1. 功能介绍及展示1.1 服务端连接1.2 客户端连接(可多个用户同时在线连接服务端)1.3 功能服务1.3.1 defaultService(默认服务)1.3.2 transform(大小写转…...

第十一章 Vue生命周期及生命周期的四个阶段

目录 一、引言 1.1. Vue生命周期的具体阶段 1.2. 每个阶段的具体作用和常用场景 1.3. 生命周期钩子函数 ​二、代码示例 三、运行效果 一、引言 Vue生命周期是指Vue组件实例从创建到销毁的整个过程。在这个过程中,组件经历了一系列的阶段,每个阶段…...

展厅展会客流显示屏的客流统计功能如何实现

随着科技的发展,展厅和展会的管理越来越智能化。客流显示屏作为一种高效的管理工具,能够实时显示参观人数,帮助主办方更好地了解客流情况,优化资源配置。本文将详细介绍展厅展会客流显示屏的客流统计功能如何实现,分为…...

golang正则表达式的使用及举例

正则表达式很强大,在一些场合如抓包,爬虫等方面很有用。在 Go语言中,正则表达式通过标准库 regexp 提供支持。使用正则表达式可以进行字符串匹配、替换和分割等操作。 以下是正则表达式的基本使用方法及示例: 1. 导入 regexp 包 …...

Flutter杂学: iOS 上启用自动填充和关联域

下面是详细的配置和代码,以确保在 iOS 上启用自动填充和关联域(Associated Domains)功能。 配置步骤 1. 在 Apple Developer 控制台中启用 Associated Domains 登录 Apple Developer。导航至您的 App ID 设置页面。找到您要配置的 App ID&…...

接口自动化-框架搭建(Python+request+pytest+allure)

使用代码如何开展接口自动化测试。 一 选择自动化测试用例 业务流程优先,单接口靠后,功能稳定优先,变更频繁不选。 二 搭建自动化测试环境 (1)安装python编译器3.7版本以上--自行安装 (2)安…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...