当前位置: 首页 > 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)安…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色&#xf…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...

麒麟系统使用-进行.NET开发

文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...

C#中用于控制自定义特性(Attribute)

我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)] 这个 C# 属性。 在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。Attr…...

Centos 7 服务器部署多网站

一、准备工作 安装 Apache bash sudo yum install httpd -y sudo systemctl start httpd sudo systemctl enable httpd创建网站目录 假设部署 2 个网站,目录结构如下: bash sudo mkdir -p /var/www/site1/html sudo mkdir -p /var/www/site2/html添加测试…...

【R语言编程——数据调用】

这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...