使用 Flutter 编写一个简单的尺子 App
女儿问我了一个题目,硬币的厚度是 2__,后面单位是什么?苦于当时身边没有尺子,没办法让她对长度单位有个清楚的认识,当时在想要是手机上能显示一把尺子就好了。
说干就干,查了一些资料,开始 coding
其实编写这个 App 只需要解决两个问题就行了:
在手机屏幕上画线,就是画刻度;刻度之间的间隔,手机屏幕两个刻度的间隔要跟现实中的 1mm 对应。先解决画线的问题,这里用到自定义 CustomPainter,代码如下
Scaffold( body: CustomPaint( painter: MyCustomPainter(), ),)
接下来 MyCustomPainter 继承 CustomPainter,需要重写 paint 方法。canvas.drawLine可以从两个坐标之间画一条线。
class MyCustomPainter extends CustomPainter { const MyCustomPainter(); @override void paint(Canvas canvas, Size size) { canvas.drawLine( Offset(0, 10), Offset(50, 10), // 从 0,10 到 50,10 画一条线 Paint() ..color = Colors.black ..strokeWidth = 3); // 线的粗细 } @override bool shouldRepaint(CustomPainter oldDelegate) => false;}
现在能画线了,再多画几条长短不一的线,加上数字,就变成了这样。
手机屏幕上画刻度
接下来解决第二个问题,计算出现实 1mm 的刻度在手机屏幕上两条线之间应该间隔多少
上面图中的刻度间隔是自己随意设的,跟现实中的尺子刻度是不相等的,要解决这个问题有两种方法:
第一种方法简单粗暴,直接用尺子量手机,然后手动调整屏幕上刻度的间距,就好了。这种方法唯一的问题是,在其他手机上刻度就不准了。这时我调整的间距是 5.95dp,已经跟现实中的尺子非常接近了。
用尺子调整手机刻度间隔
第二种方法就是用算法算出刻度的间隔,这种方法在不同手机上都可以保证刻度的准确性。
Flutter 中我们可以通过 MediaQuery.of(context).size 获取到小米13设备独立像素为Size(392.7, 856.7)dp,通过网上查询小米13屏幕尺寸是 6.36 英寸。
由此可以计算出对角线长度=915.96dp
这样就可以换算出(915.96/6.36)=148.18dp/英寸,148.18/25.4=5.83dp/毫米,上面通过尺子大致估算的是 5.95,这里算出来的精确值是 5.83。
所以我们只需要知道屏幕的尺寸,就能算出每毫米的dp设备独立像素数量,如何获取屏幕尺寸 Flutter 中并没有直接的方法,我们下次重新写一篇文章,讲一讲如何获取屏幕的尺寸。
最终效果如图:
最终效果图
最终源代码
import 'dart:math';import 'package:flutter/material.dart';class RulerPage extends StatelessWidget { const RulerPage({super.key}); @override Widget build(BuildContext context) { //获取屏幕尺寸。单位dp double height = MediaQuery.of(context).size.height; double width = MediaQuery.of(context).size.width; // 获取屏幕尺寸,这里根据自己手机修改,后面再写一篇文章讲如何获取屏幕尺寸 double screenInches = 6.36; // 对角线dp长度除于屏幕尺寸 6.36,可得到每英寸多少 dp,即为刻度间隔 double dppinch = sqrt(height * height + width * width) / screenInches / 10; // 1英寸等于 25.4毫米,除于25.4,可得到每毫米多少 dp double dppmm = sqrt(height * height + width * width) / screenInches / 25.4; return Scaffold( appBar: AppBar(title: const Text("尺子")), body: Padding( padding: const EdgeInsets.only(top: 8), child: CustomPaint( painter: MyCustomPainter(dppinch, dppmm), //将刻度间隔传到自定义画笔组件 size: Size.infinite, //size 设置为全屏幕 ), )); }}class MyCustomPainter extends CustomPainter { //接受传过来的两个刻度间隔 double mmGap; double inchGap; MyCustomPainter(this.inchGap, this.mmGap); // 定义三种粗细的画笔,用来画刻度线 Paint paint1 = Paint() ..color = Colors.black ..strokeWidth = 1; Paint paint2 = Paint() ..color = Colors.black ..strokeWidth = 2; Paint paint3 = Paint() ..color = Colors.black ..strokeWidth = 3; // 重写 paint 方法,通过循环画刻度线 @override void paint(Canvas canvas, Size size) { int i = 0; while (i * mmGap false;}
相关内容
相关资讯
-
今创集团有限公司,今创集团股份有限公司怎么样
大家好,今天小编来为大家解答以下的问题,关于今创集团有限公司,今创集团股份有限公司怎么样这个很多人还不知道,现在让我们一起来看看吧!
-
深圳中兴通讯有限公司 深圳西丽中兴通讯工厂在哪里
其实深圳中兴通讯有限公司的问题并不复杂,但是又很多的朋友都不太了解深圳西丽中兴通讯工厂在哪里,因此呢,今天小编就来为大家分享深圳中兴通讯有限公司的一些知识,希
-
深发展股票分析吉利汽车下周上会科创板整车第一股来了
深发展股票分析吉利汽车下周上会科创板整车第一股来了股市预测 深发展股票分析吉利汽车下周上会科创板整车第一股来了 2020-10-08 336 0 9月18日,科创板上市委员会公
-
上海中技投资控股股份有限公司重大资产重组停牌前股东情况的公告-上海中技投资控股股份有限公司
本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、准确性和完整性承担个别及连带责任。上海中技投资控股股份有限公司(以下简称“公司
-
上海中技投资控股股份有限公司关于公司向华兴银行委托借款的公告-上海中技投资控股股份有限公司
本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、准确性和完整性承担个别及连带责任。重要内容提示:
-
上海一居民楼挨家挨户装景观灯遭反对,“点亮”天际线如何不扰民?-上海兴盛物业有限公司
从沪闵路6666弄新梅广场小区的顶楼往东北方向极目远眺,锦江乐园的摩天轮与南方商圈的灯光交相辉映。沿着沪闵高架路收回视线,百联南方购物中心、莲花国际、中庚漫游城等商场依次林立,塑造出丰富且多变的夜景。再近处,
-
减至6000亿美元拜登救命钱要缩水
减至6000亿美元 拜登“救命钱”要缩水?包含参议院预算委员会主席伯尼・桑德斯在内的平易近主党人申饬说,假如共和党人不与平易近主党人合作,平易近主党人将寻求通过预算息争步伐来通过
-
t3账簿打印摘要宽t3账簿打印设置
本篇文章给大家谈谈t3账簿打印摘要宽,以及t3账簿打印设置对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。