Flutter 暂时没有官方的屏幕适配方案,在 Flutter 项目开发中目前大部分的适配方案都是通过比例来进行适配,是一个通用的适配方法,该适配方法也在前端、Android、iOS、小程序等开发中广泛使用...将设计图分为固定单位并给这个单位定义一个标识,例如就叫 w,然后通过获取设备分辨率,使用设备真实宽度除以设计图宽度 ,就得到了 1w 代表的真实宽度: 1w = 设备真实宽度 / 设计图宽度 如设计图尺寸是...直接使用 ScreenUtil.init 方法,传入屏幕尺寸、设计图尺寸和屏幕方向即可对 flutter_screenutil 进行初始化,代码如下: ScreenUtil.init( BoxConstraints...使用 初始化以后就可以使用 flutter_screenutil 提供的方法获取到适配后的数值进行使用了。...flutter_screenutil 提供了更简洁的调用方法,使用 Dart 扩展为 num 类型扩展了一系列属性可以方便开发者调用,上面的 api 可以通过扩展属性进行如下转换: ScreenUtil
/flutter_ScreenUtil 使用方法: 安装依赖: 安装之前请查看最新版本 dependencies: flutter: sdk: flutter # 添加依赖 flutter_screenutil...) setHeight方法主要是在高度上进行适配, 在你想控制UI上一屏的高度与实际中显示一样时使用....如果我们直接写的时候组件的尺寸这么定义,在其他尺寸的设备上未必是一半,或多,或少. 但是我们可以按比例来看,即我们要实现的宽度是实际设备的一半....1794.0) 单位px width = window.physicalSize.width //宽度 height = window.physicalSize.height //高度 //使用这个方法则无需引入包...flutter获取像素密度的方法: MediaQuery.of(context).devicePixelRatio window.physicalSize 上面两种方法得到的是一样的结果,但是window
赋值 _offsetY 方法全部代码如下: set offsetY(double value) { // 判断如果是在拖动状态下 if (isDragging) { // 不能小于最开始的位置...然后在 GestureDetector 的 onVerticalDragUpdate 方法中做操作: onVerticalDragUpdate: (e) { if (!...没错,如果这里我们在结束拖动的一秒内,再次拖动,那么这个延迟的方法就会再次运行,这样肯定是有问题的,所以我们也要进行节流与防抖。 如何进行防抖?...首先定义好方法和延迟时间: dragEndDuration = Duration(milliseconds: 1000); dragEndFunc = () { if (_lyricWidget.isDragging...也就是不走父组件的 onTap() 方法。 这里有一点,如果子组件有点击事件,并且父组件没有设置相对应的 behavior,那么事件是不会冒泡到父组件的。
# 屏幕适配 flutter_screenutil: ^1.0.2 拉取新包:flutter pub get 获取直接安装 flutter pub add flutter_screenutil。...相关的效果图: 静态路由,组件抽取,登陆注册页面 为了实现静态路由,我们来定义下登陆和注册的页面: 登录页 lib/pages/sign_in/sign_in.dart 注册页 lib/pages/sign_up...解决方案: 因为我们定义了 appBar 组件是 `Widget`,我们应该定义其为 `PreferredSizeWidget`。.../values.dart'; // 透明背景的 AppBar PreferredSizeWidget transparentAppBar({ // 使用 PreferredSizeWidget 定义...解决方案,可以尝试方法如下: initializeInterceptor(){ _dio.interceptors.add(InterceptorsWrapper( onError
其中 initUser() 方法就是用来从 SharedPreferences 中获取用户信息,如果没有获取到就为null。..._user = user; Application.sp.setString('user', json.encode(user.toJson())); } } 代码也很清晰,一共就三个方法...其余的也是用我之前写过的Flutter | 定义一个通用的多功能网络请求 Widget。 使用该控件的好处就是 省去处理网络请求的逻辑,只有返回正确数据时才会走到build回调。...BorderRadius.all(Radius.circular(radius)), child: Image.network( url, width: ScreenUtil...().setWidth(width), height: ScreenUtil().setWidth(width), child: Stack( alignment
然而并不,所谓懒汉式,即使每一次都去判断目标对象是否为null,只有为null才去创建,不为null就直接返回,懒的一批!...* @return */ public static LazySingleCase getInstance() throws InterruptedException {...(){ return StaticInternalClassSingletonHolder.staticInternalClassSingleton; } } 看一下这个,没毛病...,就是内部静态类,日后你只有调用了getInstance()方法,我内部类才会将对象创建出来,而且能保证线程安全,哎呀我真机制?...没毛病,就是枚举,他的特点是啥 1、枚举的直接父类是java.lang.Enum,但是不能显示的继承Enum 2、枚举就相当于一个类,可以定义构造方法、成员变量、普通方法和抽象方法 3、默认私有的构造方法
写在前面 上一周一直没更新代码与文章,是因为公司公费去厦门旅游来着,所以好好放松了一周。...来看一下如何定义: Wrap( spacing: ScreenUtil().setWidth(20), children: historySearchList .map((v) => GestureDetector...Colors.red, ), ], ); }); }, ) 在点击这个 IconButton 的时候调用 showDialog 方法...,所以我们要先调用 play() 方法。...还有一个地方需要注意,在 iPhone 上有些是有「控制条」的,所以我们要加上这个高度: height: ScreenUtil().setWidth(110) + Application.bottomBarHeight
, 下面是目前所想到的插件: 插件 作用 Provider[1] 状态管理,UI、数据 分离 shared_preferences[2] 本地存储数据,持久化 dio[3] 网络请求 flutter_screenutil...widget_future_builder.dart 网络请求组件 widget_net_error.dart 网络请求失败组件 其中 widget_future_builder.dart 在我上一篇文章:Flutter | 定义一个通用的多功能网络请求...BuildContext context) { if (isLoading) { Navigator.of(context).pop(); } } } 只提供了两个静态方法...逻辑如下: 1.首先判断 isLoading 是否为 true,如果正在显示 loading,那么则不作操作2.如果不为 true,则显示 loading,并把状态置为 true3.调用 then 方法...: https://pub.dev/packages/flutter_screenutil [5] fluro: https://pub.dev/packages/fluro [6] common_utils
flustars 号称“Flutter 全网最全常用工具类”,其中包括了SpUtil、ScreenUtil、TimelineUtil等常见工具类,这里我们要使用的是SpUtil这个部分,用于存储用户所选择的主题信息...我们看看ThemeData部分数据定义: ThemeData({ Brightness brightness, //深色还是浅色 MaterialColor primarySwatch, //主题颜色样本...上面只是ThemeData的一小部分属性,完整的数据定义读者可以查看 SDK。...设置初始化主题颜色 Provider.of(context, listen: false).setTheme(_colorKey);} await SpUtil.getInstance...其中onTap内的代码就是上一节中提到的设置颜色主题的方法,InkWell主要用于提供主题色的点击效果,换成GestureDetector也是可以的。
userInfo变量,当我们使用getUserInfo方法获取用户信息后,则通过setState方法对其进行赋值,从而达到修改状态的目的。...比如我们可以定义一个获取用户信息的方法getUserInfo: // service_methods.dart // 获取用户信息 Future getUserInfo() async { try{...先引入相应的文件包,然后调用方法,在then方法中接收返回值进行处理。 // 引入相应的文件包 import '.....屏幕尺寸适配 屏幕尺寸配置需要用到相关的依赖包:flutter_screenutil。 我们可以在github上找到这个包,它本质上也是一个组件,用法也比较简单。...@override Widget build(BuildContext context) { //设置尺寸(填写设计中设备的屏幕尺寸)如果设计基于360dp * 690dp的屏幕 ScreenUtil.init
如何使用DialogFragment 有两种方法 实现onCreateDialog方法 通过继承DialogFragment并且实现它的onCreateDialog(Bundle savedInstanceState...)方法来创建一个DialogFragment,这个方法返回的是一个Dialog,意味着我们需要创建一个AlertDialog,并返回。...dialog.getWindow(); WindowManager.LayoutParams lp = getDialog().getWindow().getAttributes(); lp.height = (25 * ScreenUtil.getScreenHeight...(getContext()) / 32);//获取屏幕的宽度,定义自己的宽度 lp.width = (8 * ScreenUtil.getScreenWidth(getContext()) / 9);...,还有一种方式则是覆盖父类设置的onDismissListener监听,但是需注意的时,这个监听的复写,必须在父类onActivityCreate方法调用之后。
难点 自定义一个Widget 继承Dialog class SongSheetIntroduceDialog extends Dialog 在我们输入文本之后下面的输入字数会变,可能马上你会想到使用setState...可是Dialog 并没有setState方法 我想到的解决办法就是输入文本框单独提取出来继承StatefulWidget 这样就可以使用setState方法来更新了。 不多说了分享一下代码。...import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil.../screenutil.dart'; import 'package:toofoo/common/base_component/base_image.dart'; import 'package:toofoo
那我们就自定义一个,怎么来做到展开和收回?其实就是控制歌单列表的显示和不显示,所以我们应该能想到一个组件:Offstage。...头部组件大致代码如下: Widget build(BuildContext context) { return Container( height: ScreenUtil().setWidth(...), ], ), ), );} 给整行套上 GestureDetector,点击的时候切换箭头,并且调用 widget.onSwitchTap() 方法来触发回调...}, child: Text('提交'), textColor: Colors.red, ), ], );} 直接调用 showDialog() 方法...在点删除的时候,调用 PlayListModel 里的删除方法并且通知刷新就好了。 这样整个「我的」页面大致就完成了。 4. 总结 其实这一篇没什么好总结的,把前面写好的东西拿来用就好了,非常简单。
(size * scaleWidth); return size / defaultPixel; } // 一般我们会使用scaleSize这个函数,其他特殊地方使用另外两个函数处理 //使用方法.../utils/screenUtil"; // 在标签内部写入行间样式 // 在css里写入外部样式...// 外部样式引用工具函数的方法:把外部样式用js写法表示 import { scaleSize } from "...../utils/screenUtil"; const styles = StyleSheet.create({ ListItem: { flexDirection: 'row',...,具体设置百度上都有 // 简单的方法是:如果Android实在需要自定义字体,可以使用系统监控,做ios的兼容判断,去除ios自定义字体 import { Platform } from 'react-native
} static public $instance;//声明一个静态变量(保存在类中唯一的一个实例) static public function getinstance(){//声明一个getinstance...()静态方法,用于检测是否有实例对象 if(!...name = $n; } public function getname(){ //取变量$name的值 return $this->name; } } $a = Single::getinstance...(); $b = Single::getinstance(); $a->setname('hello world'); $b->setname('good morning'); echo $a->getname...> 二、工厂模式就是一种类,具有为您创建对象的某些方法,这样就可以使用工厂类创建对象,而不直接使用new。 这样如果想更改创建的对象类型,只需更改该工厂即可。 <?
单例模式 特点: 三私一公:私有的静态变量(存放实例),私有的构造方法(防止创建实例),私有的克隆方法(防止克隆对象),公有的静态方法(对外界提供实例) 应用场景: 程序应用中,涉及到数据库操作时,如果每次操作的时候连接数据库...应用场景: 提供一种类,具有为您创建对象的某些方法,这样就可以使用工厂类创建对象,而不直接使用new。这样如果想更改创建的对象类型,只需更改该工厂即可。...return new $class; } } //调用方法: Factory::getInstance(Factory::ACLASS); 复制代码 注册树模式 特点: 注册树模式通过将对象实例注册到一棵全局的对象树上...,需要的时候从对象树上采摘的模式设计方法。...: 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。
单例模式 特点: 三私一公:私有的静态变量(存放实例),私有的构造方法(防止创建实例),私有的克隆方法 (防止克隆对象),公有的静态方法(对外界提供实例) 应用场景: 程序应用中,涉及到数据库操作时,如果每次操作的时候连接数据库...应用场景: 提供一种类,具有为您创建对象的某些方法,这样就可以使用工厂类创建对象,而不直接使用 new。这样如果想更改创建的对象类型,只需更改该工厂即可。...return new $class; } } //调用方法: Factory::getInstance(Factory::ACLASS); 注册树模式 特点: 注册树模式通过将对象实例注册到一棵全局的对象树上...,需要的时候从对象树上采摘的模式设计方法。...: 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。
定义:单例模式就是将类的构造函数进行private化,然后只留出一个静态的Instance函数供外部调用者调用。...public class SingleInit { private SingleInit(){} // 定义一个私有类,来持有当前类的实例 private static class...,无法在多线程中使用,多线可以同时进入if方法,会导致生成多个单例对象。...(); } return instance; } } 第二版:多个线程进入getInstance的时候,进行抢锁,但是这种方法不可取,严重影响性能,每次调用都要获得锁,严重影响性能。...没初始化好 AB两个线程都获得类锁,A获得B没获得,然后A直接将对象创建,释放锁。
先定义一个通用的网络请求 那既然是网络请求,那首先我们要定义一个通用的网络请求方法。 每一家后台 API 的风格都不一样,有的是 RSETful,有的是我们最熟悉的 GET、POST。...(context, '/top/album', params: params); return AlbumData.fromJson(response.data); } 我们就可以像这样来使用刚才定义好的方法...,也方便我们后续定义一个通用的 FutureBuilder。...请求数据并显示 Loading 但是,这里也有一个问题: 我们在最开始定义网络请求工具类的时候,每一个网络请求都是一个方法,而每个方法中都有或者没有参数。...Container( alignment: Alignment.center, height: ScreenUtil().setWidth(200),
画歌词 自定义组件,我们都知道是使用的 CustomPainter。 如何画文字?...这里有两种解决方案: 1.使用 TextPainter2.使用 drawParagraph 简单一点,我们就使用第一种方法好了,调用 TextPainter.paint() 方法,该方法需要传入两个参数...在上一步当中,我们通过解析歌词的方法,把一个歌词的字符串解析为一个歌词对象列表。...这里有一个细节我们要注意: 我们必须要重写 shouldRepaint 方法来通知重绘,否则组件是不会自己重新绘制的。...在开始我们绘制歌词的时候,给每个歌词之间都添加上了一个间距: y += lyricPaints[i].height + ScreenUtil().setWidth(30); 那这就好计算了,我们只需要根据当前行计算出来
领取专属 10元无门槛券
手把手带您无忧上云