成都网站建设设计

将想法与焦点和您一起共享

flutter手写识别的简单介绍

算法题有多重要 | 来看看Android-Flutter面试亲历者的经验总结

这两周面试遇到的算法题,都是需要手写实现,本人算法相当菜,面试之前也没刷题的概念,所以算法答的很不好,下面只简单说下都遇到了哪些吧。

创新互联是一家集网站建设,阿巴嘎企业网站建设,阿巴嘎品牌网站建设,网站定制,阿巴嘎网站建设报价,网络营销,网络优化,阿巴嘎网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

该问题被问到过三次,应该是相当高频的吧,第一次我只想到了下面的第一种方法,面试官很nice,引导着我给出了第二种解决方案

1-2-3-4 交换之后为 2-1-4-3.(基本没有写出来,当时面试官问我你没刷题吗,我实话实话没刷过)

被问到过两次,第一次是某公司的技术负责人,人超级好,我第一中解法用的栈实现的,然后就问我时间复杂度和空间复杂度是多少,还耐心给我讲解这两个的概念和如何计算,然后又让我想第二种解法,第二种我写的是chartAt实现,面试官又问时间复杂度和空间复杂度是多少,然后让我再想更优的解法,最后在面试官的开导下写了下面第三种实现,特感谢这位面试官。

当时大体写出来了 但是临界值判断错了

当时是写出来了,但是方法很笨,之后去看了下源码,膜拜啊

就遇到了这五个算法,其中一个出现过三次,一个出现过两次,觉得自己还是挺幸运的吧。希望大家在找工作前多看看算法吧,这个是面试必问的,而且是手写实现,最近两天也在看算法,感觉大神们的想法真的太好了,自己是很难想到这些思路的。

Flutter开发-屏蔽Widget的多点触控行为

在Flutter中我们在 Widget 实现一些手势交互通常会使用 GestureDetector 装饰器来实现,但是默认情况下, widget 是支持多点触控,但是在一些特定需求下,我们不需要多点触控的操作,或者多点触控反而给一些功能带来麻烦,而且比较不方便的是,多点触控无法通过操作 widget 或者 GestureDetector 来屏蔽掉。查阅了官方文档发现的这个玩意: RawGestureDetector

大概意思是:一个小部件,用于检测由给定手势工厂描述的手势。对于常用手势,请使用GestureRecognizer。 RawGestureDetector主要在开发自己的手势识别器时很有用。

例如:

我们可以通过RawGestureDetector来自定义手势。

有时,你可能需要禁用多点触摸或在Flutter应用程序中点击小部件。 例如,有一个列表,并且一次只能单击其中一项。 您不希望用户同时用三个手指点击或触摸并立即选择三个项。基本上,您要防止用户多次点击或多点触摸。

我们先创建一个简单的页面,页面加载一个 ListView.builder() ,

这个列表上的cell都支持多点触控,效果图:

【图】

Flutter允许在 GestureRecognizer 基类的帮助下创建自定义手势识别器小部件。 该类已经有两个抽象的实现,可以实现多次轻击和单次轻击手势。

首先创建一个自定义窗口小部件,以使其子窗口小部件只能具有单一触摸手势。

在 build() 方法中,我们将返回仅支持单点触摸手势的手势检测器小部件。 因此,我们为此创建另一个名为 _SingleTouchRecognizer 的类

现在我们回到我们的 SingleTouchRecognizerWidget 中,通过 RawGestureDetector 装饰器来定义我们刚才创建的单击手势检测器:

现在, build() 方法返回了一个 RawGestureDetector ,该 RawGestureDetector 处理 _SingleTouchRecognizer 类中的手势。接下来,我们需要在识别器类中实现这些方法。我们首先覆盖 GestureRecognizer 的 addAllowedPointer 方法。

在这里, startTrackingPointer 方法注册了将由识别器处理的相关事件。 然后, resolve() 负责确保是否允许继续进行触摸事件。

如果我们传入 GestureDisposition.rejected ,则当前的触摸事件无法处理。 因此,此触摸事件将被传递并允许其继续。 但是,如果传递了 GestureDisposition.accepted ,则将解析触摸事件,并且不会再调用其他事件。

通过handleEvent函数重置控制变量_p的值。

这样就完成了_SingleTouchRecognizer类的实现。

现在,只需要将该 Widget 包裹在想要支持单点触控的 widget 外层即可。

参考文献:

disable-multi-touch-on-a-widget-in-flutter

api.flutter.dev

Flutter了解之手势

描述了屏幕上指针(触摸、鼠标、触控笔)的位置和移动。

Flutter中可以使用Listener(功能性组件)来监听原始触摸事件

例1

例2

例3

忽略PointerEvent

手势: 描述由一个或多个指针移动组成的语义动作,如拖动、缩放、双击等。

Material大多数widget已经对tap或手势做出了响应。 例如 IconButton和 FlatButton 响应单击,ListView响应滑动事件触发滚动。

用于手势识别的功能性组件,通过它可以来识别各种手势。

例(单击)

例(添加Material触摸水波效果 InkWell组件)

例(滑动关闭 Dismissable组件)

例(单击、双击、长按)

例(滑动)

例(扫动---单一方向)

例(缩放)

GestureRecognizer是一个抽象类。

一种手势的识别器对应一个GestureRecognizer的子类。

由于手势竞争最终只有一个胜出者,所以,当有多个手势识别器时,可能会产生冲突。

在APP中经常会需要一个广播机制,用以跨页面通知。比如一个需要登录的APP中,页面会关注用户登录或注销事件,来进行一些状态更新。

这时候,一个事件总线便会非常有用,事件总线通常实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色,可以通过事件总线来触发事件和监听事件。

对于一些简单的应用,事件总线是足以满足业务需求的,如果决定使用状态管理包的话,一定要想清楚APP是否真的有必要使用它,防止“化简为繁”、过度设计。

在widget树中,每一个节点都可以分发通知,通知会沿着当前节点向上传递,所有父节点都可以通过NotificationListener来监听通知。

Flutter中将这种由子向父的传递通知的机制称为通知冒泡(Notification Bubbling)。

通知冒泡和用户触摸事件冒泡是相似的,但有一点不同:通知冒泡可以中止,但用户触摸事件不行。

通知冒泡和Web开发中浏览器事件冒泡原理是相似的,都是事件从出发源逐层向上传递,可以在上层节点任意位置来监听通知/事件,也可以终止冒泡过程,终止冒泡后,通知将不会再向上传递。

Flutter的UI框架实现中,除了在可滚动组件在滚动过程中会发出ScrollNotification之外,还有一些其它的通知,如SizeChangedLayoutNotification、KeepAliveNotification 、LayoutChangedNotification等,Flutter正是通过这种通知机制来使父元素可以在一些特定时机来做一些事情。

阻止冒泡

通知冒泡原理

Flutter 手势系列教程---Listener

Listener 它是主要的功能是用来监听屏幕触摸事件,取决于它的子组件区域范围,比如按下、移动、抬起、取消等操作时可以添加监听。

我们知道 Flutter 组件只有按钮才会有事件,那么如果我需要在文字或者某个容器上添加事件那我就需要借助 Listener

手势系列视频教程地址

Listener 常用于当手指滑动屏幕时进行隐藏键盘或者下拉刷新、上拉加载时进行事件监听。

一般在实际的开发过程中我们很少会用到 Listener 来监听手势,一般都是通过 GestureDetector 来进行监听或者使用 MouseRegion 来监听鼠标的事件,而 MouseRegion 常用于web开发中, GestureDetector 常用于app。

我们经常使用的回调函数主要有三个

我们这里主要是针对 onPointerDown 、 onPointerMove 、 onPointerUp 进行演示,因为我们在平时的开发过程中最常用到的属性就是这三个,而且其他的属性也都被废弃掉了。

我们这里先点击橙色容器,在点击一次红色容器,他们打印的结果如下。

PointerEvent 是触摸、手写笔、鼠标事件的基类。

在上文中,我们知道了什么是 Listener 并写了一个简单的案例,在使用案例的过程中我们的事件里面都带了一个 event 参数,而所有的事件最终都是继承自 PointerEvent ,那我们接下来看看 event 的参数有什么作用。

PointerEvent 的属性非常多,但在我们实际的开发过程中很少会使用到,只有在特定的情景下才会使用对应的属性。

如需要做一个全局悬浮的按钮我们会使用到 position

如需要做绘图软件我们需要用到 buttons 、 kind 等

所以大家可以根据实际的应用场景来使用对应的属性即可,下面是我对 PointerEvent 的属性进行的一个详细描述。

behavior 属性,它决定子组件如何响应命中测试,它的值类型为 HitTestBehavior ,这是一个枚举类,有三个枚举值

对子组件一个接一个的进行命中测试,如果子组件中有测试通过的,则当前组件通过,这就意味着,如果指针事件作用于子组件上时,其父级组件也肯定可以收到该事件。

在命中测试时,将当前组件当成不透明处理(即使本身是透明的),最终的效果相当于当前Widget的整个区域都是点击区域

点击组件透明区域时,可以对自身边界内及底部可视区域都进行命中测试,这意味着点击顶部组件透明区域时,顶部组件和底部组件都可以接收到事件

我们这里演示每次都是先点击绿色盒子在点击文字,以便大家能更好的分辨出这三个属性的使用区别

Listener 是 Flutter 中比较重要的功能性组件,它主要的功能是用来监听屏幕触摸事件,事件回调可以获取对应的属性来个性化定制app功能。

Flutter真香,我用它写了个桌面版JSON解析工具

Flutter支持稳定的桌面设备开发已经一段时间了,不得不说,Flutter多平台支持的特性真的很香。我本人并没有任何桌面开发的经验,但仍然使用Flutter开发出了一个桌面版小程序,功能很简单,就是对输入的json做格式化处理和转模型。

话不多说,先来看看实际效果。 项目源码地址

开发环境如下:

Flutter : 2.8.1

Dart : 2.15.1

IDE : VSCode

JSON作为我们日常开发工作中经常要打交道的一种数据格式,它共有6种数据类型: null , num , string , object , array , bool 。我们势必对它又爱又恨。爱他因为他作为数据处理的一种格式确实非常方便简洁。但是在我们做Flutter开发中,又需要接触到json解析时,就会感觉非常棘手,因为flutter没有反射,导致json转模型这块需要手写那繁杂的映射关系。就像下面这样子。

数据量少还能接受,一旦量大,那么光手写这个解析方法都能让你怀疑人生。更何况手写还有出错的可能。好在官方有个工具**json_serializable**可以自动生成这块转换代码,也解决了flutter界json转模型的空缺。当然,业界也有专门解析json的网站,可以自动生成dart代码,使用者在生成后复制进项目中即可,也是非常方便的。

本项目以json解析为切入点,和大家一起来看下flutter是如何开发桌面应用的。

要让我们的flutter项目支持桌面设备。我们首先需要修改下flutter的设置。如下,让我们的项目支持 windows 和 macos 系统。

接下来使用 flutter create 命令创建我们的模版工程。

创建完项目后,我们就可以 run 起来了。

先来看下整体界面,界面四块,分别为功能模块、文件选择模块、输入模块、输出模块。

我们在新建一个桌面应用时,默认的模版又一个Appbar,此时应用可以用鼠标拖拽移动,放大缩小,还可以缩到很小。但是,我们一旦去掉这个导航栏,那么窗口就不能用鼠标拖动了,并且我们往往不希望用户将我们的窗口缩放的很小,这会导致页面异常,一些重要信息都展示不全。因此这里需要借助第三方组件 bitsdojo_window 。通过 bitsdojo_window ,我们可以实现窗口的定制化,拖动,最小尺寸,最大尺寸,窗口边框,窗口顶部放大、缩小、关闭的按钮等。

通过 InkWell 组件,可以捕捉到手势、鼠标、触控笔的移动和停留位置

这个功能是鼠标移动后的UI交互界面。要在窗口上显示一个提示框,可以使用 Overlay 。需要注意的是,由于在 Overlay 上的 text 的根结点不是 Material 风格的组件,因此会出现黄色的下划线。因此一定要用 Material 包一下 text 。并且你必须给创建的 OverlayEntry 一个位置,否则它将全屏显示。

读取说表拖拽的文件一开始想尝试使用 InkWell 组件,但是这个组件无法识别拖拽中的鼠标,并且也无法从中拿到文件信息。因此放弃。后来从文章《Flutter-2天写个桌面端APP》中发现一个可读取拖拽文件的组件 desktop_drop ,能满足要求。

使用开源组件 file_picker ,选完图片后的操作和拖拽选择图片后的操作一致。

Textfield 如果要显示富文本,那么需要自定义 TextEditingController 。并重写 buildTextSpan 方法。

在做导出功能时遇到下列报错,保存提示为没有权限访问对应目录下的文件。

通过Apple的开发文档找到有关权限问题的说明。其中有个授权私钥的key为 com.apple.security.files.downloads.read-write ,表示 对用户的下载文件夹的读/写访问权限 。那么,使用Xcode打开Flutter项目中的mac应用,修改工程目录下的 DebugProfile.entitlements 文件,向 entitlements 文件中添加 com.apple.security.files.downloads.read-write ,并将值设置为YES,保存后重启Flutter项目。发现已经可以向下载目录中读写文件了。

当然,这是正常操作。还有个骚操作就是关闭系统的沙盒机制。将 entitlements 文件的 App Sandbox 设置为NO。这样我们就可以访问任意路径了。当然关闭应用的沙盒也就相当于关闭了应用的防护机制,因此这个选项慎用。

原文地址:


分享文章:flutter手写识别的简单介绍
地址分享:http://chengdu.cdxwcx.cn/article/dsgoegi.html