Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具

这篇具有很好参考价值的文章主要介绍了Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Flutter笔记
发布一个模块scale_design
设计师尺寸适配工具与常用组件库

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134210226
模块地址:https://pub.dev/packages/scale_design
仓库地址:https://github.com/jacklee1995/flutter_scale_design



1. 概述

这次做的 scale_design 模块旨在解决移动端适配方面的问题。需要指出的是,Flutter是一个跨平台的框架,它不仅仅把目光放在移动端,因此如果你考虑的是桌面端和 Web 开发,那么这个模块目前不适合你。

移动端上,由于屏幕小、屏幕尺寸固定的,他有一个特点是,整个页面的应用窗口即屏幕,一经初始化则大小为定值——不会像PC应用那样,

2. UI设计规范(以Android为例)

2.1 逻辑分辨率与单位

在Android中,与屏幕相关的两个重要概念是逻辑分辨率和单位。逻辑分辨率是您在应用程序中使用的虚拟分辨率,以确保应用在不同设备上具有一致的外观。为了实现这一目标,Android引入了两个主要单位:dpsp。接下来,分别介绍。

Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具,Dart语言与Flutter框架开发笔记,前端、桌面端、移动端、UI、构建工具,Flutter,Dart,scale design

2.1.1 dp(密度独立像素)

dp 是用于非文字元素的长度单位。它的关键特点是,它是一个与屏幕密度相关的单位。在屏幕像素密度为160dpi的情况下,1dp等于1px。然而,在更高或更低的屏幕密度下,1dp的实际像素数会有所不同。这使得在不同设备上相同的dp大小的元素看起来差不多。因此,使用dp可以确保元素的大小在不同屏幕上具有一致性。

2.1.2 sp(尺寸独立像素)

sp 是用于文字大小的单位。它类似于dp,但具有一个特殊的特性,即允许用户在设备上调整字体大小,而不会影响其他元素的大小。这对于用户可访问性和个性化设置非常重要。

2.2 屏幕密度与单位之间的关系

屏幕密度通常以 dpi (每英寸点数)为单位表示。它描述了在每英寸长度内的像素数,即像素密度。这与dp和px之间的关系密切相关。以下是一些常见的屏幕密度版本以及它们的dp和px之间的转换关系:

屏幕密度版本 DPI dp与px的比例
ldpi(低屏幕密度) 120 1dp = 0.75px
mdpi(中等屏幕密度) 160 1dp = 1px
hdpi(高屏幕密度) 240 1dp = 1.5px
xhdpi(超高屏幕密度) 320 1dp = 2px
xxhdpi(超超高屏幕密度) 480 1dp = 3px
xxxhdpi(超超超高屏幕密度) 640 1dp = 4px

了解不同屏幕密度版本的转换关系可以帮助开发者在应用程序中创建适应不同设备的元素。这对于确保用户体验的一致性至关重要,无论用户使用的是低密度还是高密度屏幕。这也有助于开发者更好地理解Android系统中的长度单位和分辨率的概念,以便更好地开发和设计应用。

3. UI适配的需求背景

为了解决不同屏幕尺寸和密度带来的UI适配问题,需要一种适配方案。提出方案面临的背景是:

移动应用在不同设备上运行,这些设备具有各种不同的屏幕尺寸和像素密度。如果开发者不考虑这些因素,应用可能会在某些设备上看起来不协调或缺乏一致性。

解决这个问题的关键点是使用 逻辑像素单位(dp) 来测量和布局UI元素。

原因很简单:

  • 由于逻辑像素是与屏幕密度无关的单位,因此它们可以确保在不同设备上,相同的dp大小的元素看起来差不多。

为了实现这一思想,需要完成了步骤:

  1. 定义一个基准的设计尺寸,通常由设计师确定,作为UI元素的标准大小。

  2. 使用比例计算,将设计中的尺寸值除以基准设计尺寸,然后乘以当前设备的屏幕尺寸,以获得在当前设备上的适当尺寸。

  3. 提供辅助函数,如 scaleHeightscaleWidthscaleFont等函数,以简化比例计算的过程,使开发者能够轻松地创建响应式布局。

其中, scaleHeight 等函数包含在 scale_design 库中。(scaleHeight、scaleWidth和scaleFont 等函数是基于逻辑像素单位(dp)进行计算的)

这里思想的核心目标是实现UI元素的一致性,无论用户使用的是小屏幕还是大屏幕,低分辨率还是高分辨率的设备。它旨在解决跨设备UI适配的挑战,以提供更好的用户体验。

4. scale_design 的安装和初始化

4.1 scale_design 的安装

运行以下命令:

flutter pub add scale_design

这将向你的包的 pubspec.yaml 配置文件依赖字段中添加一行scale_design的记录,并运行一个隐式的flutter pub get,版本默认为当前最新版本。

4.2 scale_design 的初始化

要在项目中正确使用 scale_design,需要在项目启动之初获取屏幕的基本信息,即初始化。

可以在应用返回跟组件前调用静态初始化方法,比如最简单的情况:

import 'package:flutter/material.dart';
import 'package:flutter_scale/flutter_scale.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    // 用首选的标准屏幕尺寸初始化Scale类
    // 这个标准屏幕尺寸一般由设计师(美工)给
    Scale().init(context, standardWidth, standardHeight);

    return MaterialApp(
      // ...
    );
  }
}

很多实际项目,你希望将项目的一些配置全部写在同一个配置文件中,在 mian.dart 写一个初始化函数进行各种初始化操作。就比如在配置文件中:

class LayoutConfigs {
  static double standardWidth = 812.0;
  static double standardHeight = 375.0;
}
import 'package:flutter/material.dart';
import 'package:scale_design/scale_design.dart';
import 'app/config.dart'; // 导入你的配置文件

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // 初始化方法
  Future<void> initialization(BuildContext context) async {
    // 初始化屏幕尺寸比例缩放
    Scale().init(
      context,
      LayoutConfigs.standardWidth,
      LayoutConfigs.standardHeight,
    );
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: FutureBuilder(
        future: initialization(context),
        builder: (context, snapshot) {
          return const MyHomePage(
            title: 'Scale Design Demo',
          );
        },
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ...
      ),
    );
  }
}

5. 字体尺寸适配方案

字体尺寸适配的关键目标是在不同的设备和屏幕尺寸下提供
“一致的用户体验”,即:
确保文本内容既不会过大导致溢出,也不会太小导致难以阅读

我们这里的具体方案仍然是通过根据屏幕尺寸自动调整字体大小,可以有效应对多样化的移动设备,从小屏幕手机到大屏幕平板电脑。这种字体尺寸适配方案有助于提高用户体验,使应用程序更加灵活和适应不同的使用环境。

但是这个方案如何落实呢?

scale_design 模块的 scaleFont 方法是上述字体尺寸适配方案的具体实现之一。它是一个用于动态计算字体大小的工具,基于屏幕尺寸和设计标准的宽度之间的比例。这个方法的核心思想是将字体大小调整为适应不同屏幕宽度的需求,以保持文本内容的可读性。

具体而言,scaleFont 方法的应用如下:

  • 基准字体大小: 开发者首先定义了一个基准字体大小,通常是在设计阶段确定的。这个基准字体大小是文本在设计标准的屏幕上的理想大小。
  • 屏幕宽度比例: scaleFont 方法获取当前设备的屏幕宽度和设计标准的宽度之间的比例。这个比例反映了当前屏幕与设计标准的相对大小。
  • 动态调整: 使用上述比例,scaleFont 方法将基准字体大小动态调整为适合当前屏幕的字体大小。这确保了文本内容在不同屏幕尺寸下都能够以一致的比例呈现。

事实上,如果屏幕宽度比例为1,意味着当前屏幕的宽度与设计标准的宽度相等,无需进行字体大小的缩放。在这种情况下是以一个特例:

double scaleFont(double fontSize) {
  return fontSize;
}

scaleFont 方法返回的字体大小将与设计时的大小保持一致,不会进行任何缩放。
然而 scale_design 中考虑到对于一般的情况,是按照上面几个步骤的完整实现:

double scaleFont(double fontSize) {
  // 获取当前设备的屏幕宽度
  double screenWidth = Scale.screenWidth;

  // 获取设计标准的宽度
  double standardWidth = Scale.standardWidth;

  // 计算字体大小的比例
  double scale = screenWidth / standardWidth;

  // 根据比例调整字体大小
  return fontSize * scale;
}

即:

double scaleFont(double fontSize) {
  return Scale.screenWidth Scale.standardWidth/ ;
}

6. 在项目中调用工具函数

scaleWidth 和 scaleHeight

依据设计师的来稿,在项目中有需要用到一般元素的宽高的时候,使用scaleWidth、scaleHeight来实现宽高的dp表示,如:

import 'package:scale_design/scale_design.dart';

// ...
scaleWidth(320.0);
scaleHeight(60.0);

perWidth 和 perHeight

perWidthperHeight 是两个函数,用于处理屏幕尺寸适配,具体功能如下:

  1. perWidth 函数:

    • perWidth 用于获取屏幕宽度的 1/n 部分,其中 n 是传入的参数。
    • 它接受一个 n 参数,表示要获取屏幕宽度的多少分之一,例如 n 为 2 时,表示获取屏幕宽度的一半。
    • 如果 n 大于 0,函数将返回屏幕宽度除以 n 的结果;否则,会抛出异常。
    • 这个函数通常用于根据屏幕宽度的比例来设置 UI 元素的宽度,以实现屏幕尺寸适配。
  2. perHeight 函数:

    • perHeight 用于获取屏幕高度的 1/n 部分,其中 n 是传入的参数。
    • 它接受一个 n 参数,表示要获取屏幕高度的多少分之一,例如 n 为 3 时,表示获取屏幕高度的三分之一。
    • 如果 n 大于 0,函数将返回屏幕高度除以 n 的结果;否则,会抛出异常。
    • 类似于 perWidthperHeight 主要用于根据屏幕高度的比例来设置 UI 元素的高度,以实现屏幕尺寸适配。

这两个函数对于创建响应式布局和动态适应不同屏幕尺寸的应用程序非常有用。开发者可以使用它们来设置 UI 元素的尺寸,以适应不同的设备屏幕,从而提供更好的用户体验。

import 'package:scale_design/scale_design.dart';

// ...
perWidth(2);   // 屏幕宽度的1/2
perHeight(2);   // 屏幕宽度的1/2

scaleFont

scaleFont 函数是用于根据屏幕大小进行字体大小适配的工具。例如:

Text(
  'Hello, World!',
  style: TextStyle(fontSize: scaleFont(18)),
);

不过,这可以使用使用对应于 Text 组件的 T 组件表示,那将更加简洁(T组件也需要导入该scale design库)。

7. 对原生Flutter组件的包装

包装的目的在于更加简单地使用一些常见地组件,比如 Flutter 中的 ElevatedButton ,在 Scale Design 库中的对应品是 ElevatedBtn,不再需要使用 scaleXXX 这些函数来指定宽高,传入的 double 数值已经在内部做了转换。并且默认情况下,不需要使用 Text来在按钮上实现文字,直接传入字符串默认就是文字,除非你硬性指定 child 属性,这时传入的text不再有效。

一个例子是,我们在项目中可以直接基于 ElevatedBtn 二次封装直接用于特定功能的组件:

import 'package:flutter/material.dart';
import 'package:scale_design/scale_design.dart';

class SubmitButton extends StatelessWidget {
  final String text;
  final Function()? onPressed;
  final double width;
  final double height;
  final double size;
  final Color color;

  const SubmitButton(
    this.text, {
    super.key,
    this.onPressed,
    this.width = 320.0,
    this.height = 49.0,
    this.size = 18.0,
    this.color = const Color.fromARGB(255, 255, 98, 7),
  });

  
  Widget build(BuildContext context) {
    return ElevatedBtn(
      text,
      onPressed: onPressed,
      width: width,
      height: height,
      fontSize: size,
      backgroundColor: color,
    );
  }
}

class IconBtn extends StatelessWidget {
  final IconData icon;
  final Function()? onPressed;

  const IconBtn({super.key, required this.icon, required this.onPressed});

  
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(icon),
      onPressed: onPressed,
      iconSize: scaleFont(24), // 调整图标大小
    );
  }
}

当然这个 SubmitButton 的 width、height 也是基于 dp 的。然后我们可以将这个按钮用于它适应的具体化场景,比如下面是我一个项目中登陆页面的表单提交:

SubmitButton("继续", onPressed: () async {
  if (_formKey.currentState!.validate()) {
    _formKey.currentState!.save();
    await authService.login().then((String? token) {
      if (token != '' && LoginViewController.to.remember) {
        LoginViewController.to.saveLoginInfo(
          authService.email.value,
          authService.password.value,
        );
        goToMallViewPage(index: 0, type: 'offAll');
      } else {
        LoginViewController.to.clearSavedPassword(
          authService.email.value,
        );
      }
    });
  }
}

Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具,Dart语言与Flutter框架开发笔记,前端、桌面端、移动端、UI、构建工具,Flutter,Dart,scale design

类似的,scale_design 中还有 T 组件,是Text组件的替代,TSpan组件相当于对应的TextSpan组件,等等。不过也不全是这类对于原生的包装,也有一些组件是常见于项目的,但本身并不是基于 dp 封装的,需要使用 scaleXXX 这些函数传入对应的dp值。文章来源地址https://www.toymoban.com/news/detail-744526.html

到了这里,关于Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter笔记:GetX模块中不使用 Get.put 怎么办

    Flutter笔记 GetX模块中不使用 Get.put 怎么办 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134006728 依赖注入(Dependency Injection,DI)是一种编程模式,它旨在管理和注入类之间的依赖关系,以提高代码

    2024年02月08日
    浏览(48)
  • Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(上)

    Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash(上) 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134098877 【介绍】:本文完全基于Flutter绘图技术绘制一个精美的Dash图标(上

    2024年02月07日
    浏览(141)
  • Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(中)

    Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash(中) 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134098877 【介绍】:本文完全基于Flutter绘图技术绘制一个精美的Dash图标(中

    2024年02月06日
    浏览(91)
  • Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(下)

    Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart吉祥物Dash 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134098955 另见: 上上篇文章:《完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物

    2024年02月07日
    浏览(48)
  • 多尺度特征提取模块 Multi-Scale Module及代码

    现在很多的网络都有多尺度特征提取模块来提升网络性能,这里简单总结一下那些即插即用的小模块。 禁止抄袭或转载!!! 最早的应该算是在ILSVRC2014比赛分类项目获得第一名的GoogLeNet(Incepetion V1),该网络设计了 Inception module 。 后来出现了很多进化版本:Incepetion V1-V3、

    2024年02月05日
    浏览(39)
  • Flutter Android开发 梳理Google Material Design颜色体系

    做安卓开发(Kotlin语言),Flutter开发的人员应该都听说过谷歌一直推崇的Material Design,而Material Design Color是其推崇的颜色体系,具体来说,Material Design Color是一套旨在帮助设计师和开发者创建视觉吸引力和一致性界面的指南。它不仅包括了丰富的颜色选择,还提供了如何有效

    2024年02月20日
    浏览(38)
  • 一图看懂 setuptools 模块:一个功能齐全、积极维护且稳定的库,旨在方便打包Python项目,资料整理+笔记(大全)

    本文由 大侠(AhcaoZhu)原创,转载请声明。 链接: https://blog.csdn.net/Ahcao2008 全文介绍python的 setuptools 模块(一个功能齐全、积极维护且稳定的库,旨在方便打包Python项目)、函数、类及类的方法和属性。 它通过代码抓取并经AI智能翻译和人工校对。 是一部不可多得的权威字典类

    2024年02月06日
    浏览(48)
  • python图形界面化编程GUI(三)事件绑定(鼠标和键盘、OptionMenu、scale、颜色、文件对话框、菜单和工具栏、ttk子模块)

    Tkinter类 名称 简介 Toplevel 顶层 容器类,可用于为其他组件提供单独的容器,类似于窗口 Button 按钮 代表按钮组件 Canvas 画布 提供绘图功能,包括直线、矩形、椭圆、多边形、位图等 Entry 单行输入框 用户可输入内容 Frame 容器 用于装载其他GUI组件 Label 标签 用于显示不可编辑

    2024年02月12日
    浏览(45)
  • Ant Design Pro项目中 提示:找不到模块“@ant-design/pro-components”或其相应的类型声明

    Ant Design Pro中在使用 StatisticCard 指标卡组件时候,按照官方的文档从“@ant-design/pro-components”中引入这个组件发现会报错 提示找不到模块“@ant-design/pro-components”或其相应的类型声明 也就是说 Ant Design Pro 脚手架创建的项目中,默认没有引入这个依赖包,于是去package.json中看了

    2024年02月11日
    浏览(68)
  • flutter Android 打包和发布

    环境 mac vscode 项目简易打包 打开VScode终端:输入命令flutter build apk即可 可能报错: w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath: 修改android/build.gradle 中版本信息 项目正式打包 1、版本修改 在pubspec.yaml中,修改版本信息 可能感觉很疑惑,

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包