GetX 代码生成 IDEA 插件,超详细功能讲解(透过现象看本质)

前言
本文更新非常频繁,最新内容请查看:最新内容---GetX代码生成IDEA插件功能说明
本文章不是写 getx 框架的使用,而且其代码生成 IDEA 插件的功能讲解
我之前写过俩篇很长很长的 getx 文章
一篇入门使用:Flutter GetX使用---简洁的魅力!
一篇原理深度剖析:Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文)
鱼和渔都已经交给大家了,就没必要去赘述了

同时,我也写了一个 getx 代码生成插件:getx_template,这个工具相当于钓鱼座椅(让你更舒服的钓鱼或吃鱼?)吧!初期功能十分简单,就是生成单页面相应的模块代码,连个记忆选项功能都没有,基本上就是个塑料座椅的程度
但是随着大量
叼毛靓仔 给我提的各种需求,这个插件变的已经有点复杂了尤其是涉及 Select Function 模块,有些人可能都搞不懂选中的功能按钮是啥意思,就一通全部勾中。。。
所以,本凤雏想详细的,和各位卧龙谈谈这个工具方方面面的功能,希望能帮助各位节省点开发时间
兄弟们,我实在不想写水文;但是这个工具一个功能按钮,改变的代码可能很少,其背后所蕴含的东西,可能需要大量的笔墨去描述,这边就统一的和各位彦祖于宴亦菲们,说道说道。

本文长期更新,如果想知道插件每次详细更新内容,可以点进来看。
代码生成
Plugins 里搜索 getx 即可

对比
早期代码生成弹框,可选功能比较少,当时还不支持持久化储存
淦,图标也丑

这是多次完善后的功能选择弹窗

鄙人是个十足的颜值党,这次最新版本的页面,我做了很多考量
首页随着各位靓仔提的各种需求,Select Function,从最初的俩个功能,增加到现在的七个功能
随着功能按钮的增多,在 dialog 上平铺下来,整个 dialog 的高度会变得相当的长
最重要的是:会让使用者,不明确 Function 里面的重点功能按钮是什么!
基于上述的思考,我绞尽脑汁的想解决这个问题
方案一:我本来是想做一个折叠收纳区域,次要功能按钮放在折叠区域中
用 swing 一通写后,发现效果是真的丑,收纳的时候,高度计算也有问题:放弃
方案二:这个是我在翻 swing 控件的时候,发现了 JBTabbedPane 这个 tab 控件
效果简洁优雅,完爆折叠思路:采用
这次我全面的改善了 dialog 布局问题
以前的整个 dialog 的长宽是写死的,在高尺寸的分辨率屏幕上会存在问题
这次,发现了 pack 方法的妙用(swing 菜狗的辛酸泪),全面重构的界面布局逻辑
这一次,在 48 寸的屏幕上,肯定不会出现下面这种情况了

虽然我没试,但是我对自己的代码有信心

模式选择
这里提供俩种大的模式选择:default,easy
来看下区别
default 模式

view
logic
state
Easy 模式

view
logic
总结
上面的 default 模式和 easy 模式,从代码上看,还是能看出很明显的区别
Default 模式比 Easy 模式多了一个 State 层
State 是专门用来存放页面变量和初始化相关变量数据的
我曾写过一个比较复杂模块
页面的变量达到几百个(涉及到复杂的表单提交),与用户的事件交互也有几十个
整个模块很多逻辑依靠相关变量去标定,会初始化很多不同数据,State 层的代码几乎快一千行
所以当业务逐渐的复杂,State 层并不薄,他支撑着整个模块的逻辑标定和扭转
除非是肉眼可见的业务极简模块,推荐使用 Easy 模块;其余的情况推荐使用 Default 模式
main(主要功能)
useFolder,usePrefix
useFolder 和 usePrefix 功能比较简单,这里就放在一起讲了
useFolder
本项功能是默认选中的,会在创建的多个文件外,创建一个文件夹,方便管理

usePrefix
一些小伙伴喜欢在各层:view,state,logic,前加上 module 名的前缀(小写+下划线)
这边也为大家提供了一个这样的可选功能

isPageView
请注意:isPageView 和 autoDispose 按钮不能同时选中,他们俩都能解决 PageView 中存的问题,选择其中一按钮,另一按钮会自动取消勾选
这算是一个非常有用的功能了
如果大家在 PageView 中使用 getx,可能会发现,所有的子页面中的 GetXController,一下全被注入了!并不是切换到对应页面,注入对应的 GetXController!
分析
我们可以来分析下,为什么会发生这种情况,来看下:FunctionPage
我们注入的步骤,是放在类的成员变量作用域
这个作用域是在实例化构造函数之前起效的
所以我们在添加被实例的 Page 的时候,成员变量的作用域直接被触发,GetXController 就被注入
PageView 触发机制
PageView 触发被添加 Widget,是触发对应 Widget 的 build 方法
切换到哪个 Widget,就触发对应 Widget 的 build 方法
有了上面这层理解,就很容易解决 PageView 的问题了
只需要将注入过程放在 build 方法中
因为我们使用的是 StatelessWidget,并不需要考虑其刷新问题,只有它的父节点刷新,它才会被刷新
GetX 存储对象使用的 putIfAbsent 方法,只会存储第一次注入对象,后续相同类的对象直接忽略,这能避免很多问题
处理
所以此功能只需要改变 View 文件里,GetXController 的注入位置,其它文件不需要变动

addBinding
binding 是为了统一管理 GetXController,来看下 binding 和非 binding 的区别

非 Binding
view
logic
Binding:需要配套 GetX 路由
binding
view
logic
需要在路由模块绑定下这个 binding
总结
binding 文件里面,使用的是懒注入:在使用了 find 方法的时候,才会真正的注入
所以在 view 里面,就需要将 put 改成 find 就行了,总结下
增加 binding 文件,使用懒注入
view 文件,put 改成 find
需要在 getx 路由模块,对应的页面上绑定 binding 实例
minor(次要功能)
addLifecycle
这是个非常简单的功能,就放在次要功能 tab 下
一些小伙伴,logic 模块需要经常写 onReady 和 onClose 回调,懒得每次手写;所以在插件里添加了自动补上这俩个回调的功能
仅仅 Logic 文件有区别

autoDispose
该功能正如名字一样:自动释放 GetXController
实际上,这是个非常重要的功能,但是实现的太不优雅了,就把它移到了次要功能 tab 里面了
GetX 内部对回收 GetXController,做了很多处理,释放的操作是在 GetX 路由处理的;但是,业务多变复杂,导致某些 GetXController 很难被框架自动释放,例如:
PageView 的子页面
使用 GetX 封装的复杂组件
不使用 GetX 路由
上面的这些情况都无法自动回收 GetXController;为此,我在插件里,给出了一个解决方案,区别只在 view 文件
通用解决方案

view
logic
上面这种方案,是基本都能解决回收 GetXController 问题(除非你手动开启保活 GetXController 的参数)
但是!这里面需要使用 StatefulWidget!多了很多代码!这太不优雅了!
优化解决方案
上面的是个通用解决方法,你不需要额外的引入任何其它的东西;但是这种方案用到了 StatefulWidget,代码多了一大坨,让我有点膈应
鄙人有着相当的强迫症,想了很久
本来是想 GetBuilder 写个回收逻辑,然后提个 PR 给作者
发现 getx 框架已经做了这样的处理,但是,需要配套一个参数开启使用
在 GetBuilder 里面写了回收逻辑:对 Obx 刷新模块无法起效,Obx 刷新控件内部无法定位到 GetXController,所以无法做回收操作
那只能从外部入手,我就写了一个通用控件,来对相应的 GetXController 进行回收
这个通用控件,我也给 getx 提了 PR,一直在审核
就算这个控件的 PR 通过了,集成到 getx 中,getx 低版本也无法使用,没辙
这边我给出这个通用回收控件代码,各位可以自行复制到项目中使用
GetBindWidget
该控件可以回收单个 GetXController(bind 参数),可以加上对应 tag(tag 参数);也可以回收多个 GetXController(binds),可以加上多个 tag(tags 参数,请和 binds 一 一 对应;无 tag 的 GetXController 的,tag 可以写成空字符:"")
使用非常的简单
总结
对于上面的优化方案
就算你不使用 GetX 路由,你也可以很轻松的回收对应的 GetXController 了
这种回收方式在 GetBuilder 和 Obx 俩种刷新机制中,都是通用的
回收的时机:是当前页面被回收的时候
唯一麻烦的:需要你手动把 GetBindWidget 这个控件,引入到自己的项目中

LintNorm
pub:lint库
这个功能,乍一看,大家估计都懵逼了;这要不是我写的,我看了也懵逼啊

但是,这个功能,真是少部分强迫症患者的福音
因为 getx 作者,在 demo 项目里面,引入的 lint 库,一些小伙伴可能也用了这个库
lint 是一个严格规则的代码库,对于代码相应不规范的地方,会通过 IDEA 给与提示;对于我们很多认为合理的代码,有时候可能也会给出相应的警告
在生成的模板代码,有几行就会在 lint 规则下被警告
这俩个注入代码,都会自动推导出对应的类型;但是在 lint 规则下,会有黄色下划线警告

需要做这样的调整,才能去掉警告

选中 lintNorm 按钮,就会以下面这种形式生成模板代码;所以说这个功能是强迫症患者福音。。。
对于用 lint 这种强规则的人,我表示:

pub:flutter_lints
最近 Flutter 在新建项目里面,默认加上了 flutter_lints 这个库,这个库的规则宽松很多,规则基本也是规范 flutter 的写法
生成了模板代码里面,会有一个警告

需要做如下调整,才能去掉警告

当你开启 lintNorm,也会帮你补上生成页面的构造函数
template(切换模板命名)
场景
该功能提供了切换模板命名的操作
提供三套模板命名,只提供三套,不会再多增了
内部对持久化模块进行了重构
不重构不行,增加了大量的持久化变量,还全部使用静态变量着实不优雅
增加了数据类,来记录大量重复的持久化数据
为什么要提供切换模板命名的功能?
当业务逐渐的复杂,很多时候,复杂的通用组件,也可以使用 getx 去封装
但是使用插件生成对应模块,view 模块的 Widget 可能还是为 XxxPage
上面这种情况就不太友好了,你可能需要 XxxComponent 或者 XxxWidget
虽然,可以在设置里重命名后缀名,但是这样可能又对生成 Page 模块产生影响
所以,这里提供三套模板命名切换,可以快速切换到你需要的自定命名方式
功能演示
插件窗口增加三套模板切换
选择 Template,提供三套切换模板命名:Page、Component、Custom
默认 Page

三套模板命名都支持自定义修改
上面的切换,对应设置页面的三套自定义通用后缀
设置页面布局也重写了,看起来更舒服一些,对整体空间利用率也更高了

示例
mode 选择:Easy;Template 选择:Component

看下代码
view
logic
Wrap Widget
这是一个非常好用的功能
目前支持四种 Wrap Widget 类型:GetBuilder,GetBuilder(autoDispose),Obx,GetX
使用注意事项:鼠标点击在 Widget 上即可,然后按 alt+enter;请勿双击选中 Widget 名字
GetBuilder

GetBuilder(Auto Dispose)
assignId 设置为 true:GetBuilder 就会在页面被回收的时候,自动回收其指定泛型的 GetXController

Obx
说下这里为什么不用箭头符号,如果需要包裹的 Widget 非常长的话,使用箭头符号后,格式化后的代码并不整齐
考虑到这种情况,所以使用了 return 形式

GetX
这个组件我虽然不太喜欢用,但是指不定有喜欢用的小伙伴,就加上了

可选择性关闭

快捷代码生成
插件也为大家提供了,输入关键字生成快键代码片段的功能
请注意:关键字前缀为getx
路由模块
getxroutepagemap

getxroutename

getxroutepage

getxto,getxtoname

getxoff,getxoffall,getxoffnamed,getxoffallnameed

依赖注入
put

find

lazyPut

业务层
GetxController

getxfinal,getxfinal_

getxget,getxget_

getset,getset_

其它
getsnakebar,getdialog,getbottomsheet

getxbuilder,getxobx

binding

还有其它的一些快捷代码,自行感受喽~~
版本更新说明
3.2.x
增加模板切换功能,大幅度优化内部持久化方式
重构设置页面布局
支持 flutter_lints 规则
3.1.x
显著的提升整体页面布局
高尺寸屏幕不会再出现坑比问题了
支持 lint 规则(lintNorm)
改善快捷代码提示功能,“get”前缀改成为“getx”
getx 为前缀,会让提示代码被很多系统代码淹没,改为 getx 之后就可以一目了然了
插件描述页面,添加本篇文章链接
3.0.x
项目代码从 Java 迁移为 kotlin
ModuleName 输入:首字母小写,内部会自动标为大写
增加大量快捷代码片段生成
插件项目逻辑重构,界面层和逻辑层分离
Wrap Widget 增加:GetBuilder(Auto Dispose)
可自动回收对应的 GetXController
增加 PageView 解决方案
修复一些 bug
2.1.x
重大更新!
增加 Wrap Widget:GetBuilder,Obx,GetX
增加快捷代码片段生成
大幅度优化插件布局
增加完善生命周期回调功能(addLifecycle)
添加 binding 功能(addBinding)
1.5.x
增加记忆功能(记忆选择的按钮)
添加 GetXController 自动回收功能(autoDispose)
支持修改通用后缀:view,logic,state
调整插件说明,修复一些 bug
1.3.x
适配多版本的 IDEA(之前只适配了一个 IDEA 版本,坑)
添加插件 logo
增加一篇 getx 英文文章(机翻自己的博客文章)
改善插件描述
1.2
调整描述内容
1.1
修复增加前缀时,发生的导包异常问题
1.0
你可以使用本插件生成大量的 getx 框架代码
这能大大提升你的效率
如果有任何问题,欢迎给我提 issue;提之前:请先思考下,合不合理
最后
在不断完善这个插件的时候,也是我不断思考的一个过程,
感谢大家提的各种蛋痛的需求

能让这个插件一点点的完善,以至于现在,,能真正的帮助靓仔们节省一点开发时间

系列文章 + 相关地址
版权声明: 本文为 InfoQ 作者【小呆呆666】的原创文章。
原文链接:【http://xie.infoq.cn/article/9a06d6a80479ae0d93e5c49e8】。文章转载请联系作者。
评论