• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

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

android 搞代码 3年前 (2022-03-01) 43次浏览 已收录 0个评论
文章目录[隐藏]

前言

本文章不是写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
<code class="dart">class TestPage extends StatelessWidget {
  final logic = Get.put(TestLogic());
  final state = Get.find<TestLogic>().state;

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
  • logic
<code class="dart">class TestLogic extends GetxController {
  final TestState state = TestState();
}
  • state
<code class="dart">class TestState {
  TestState() {
    ///Initialize variables
  }
}

Easy模式

  • view
class TestPage extends StatelessWidget {
  final logic = Get.put(TestLogic());

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
  • logic
<code class="dart">class TestLogic extends GetxController {

}

总结

下面的default模式和easy模式,从代码上看,还是能看出很显著的区别

  • Default模式比Easy模式多了一个State层
  • State是专门用来寄存页面变量和初始化相干变量数据的

我曾写过一个比较复杂模块

  • 页面的变量达到几百个(波及到简单的表单提交),与用户的事件交互也有几十个
  • 整个模块很多逻辑依附相干变量去标定,会初始化很多不同数据,State层的代码简直快一千行
  • 所以当业务逐步的简单,State层并不薄,他撑持着整个模块的逻辑标定和扭转

除非是肉眼可见的业务极简模块,举荐应用Easy模块;其余的状况举荐应用Default模式

次要性能(main)

useFolder,usePrefix

useFolder和usePrefix性能比较简单,这里就放在一起讲了

useFolder

本项性能是默认选中的,会在创立的多个文件外,创立一个文件夹,方便管理

usePrefix

一些小伙伴喜爱在各层:view,state,logic,前加上module名的前缀(小写+下划线)

这边也为大家提供了一个这样的可选性能

isPageView

这算是一个十分有用的性能了

如果大家在PageView中应用getx,可能会发现,所有的子页面中的GetXController,一下全被注入了!并不是切换到对应页面,注入对应的GetXController!

<code class="dart">PageView(children: [
    FunctionPage(),
    ExamplePage(),
    SettingPage(),
])

剖析

咱们能够来剖析下,为什么会产生这种状况,来看下:FunctionPage

<code class="dart">class FunctionPage extends StatelessWidget {
  final logic = Get.put(TestLogic());
  final state = Get.find<TestLogic>().state;

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

咱们注入的步骤,是放在类的成员变量作用域

  • 这个作用域是在实例化构造函数之前起效的
  • 所以咱们在增加被实例的Page的时候,成员变量的作用域间接被触发,GetXController就被注入

PageView触发机制

  • PageView触发被增加Widget,是触发对应Widget的build办法
  • 切换到哪个Widget,就触发对应Widget的build办法

有了下面这层了解,就很容易解决PageView的问题了

  • 只须要将注入过程放在build办法中
  • 因为咱们应用的是StatelessWidget,并不需要思考其刷新问题,只有它的父节点刷新,它才会被刷新
  • GetX存储对象应用的putIfAbsent办法,只会存储第一次注入对象,后续雷同类的对象间接疏忽,这能防止很多问题

解决

所以此性能只须要扭转View文件里,GetXController的注入地位,其它文件不须要变动

addBinding

binding是为了对立治理GetXController,来看下binding和非binding的区别

非Binding

  • view
<code class="dart">class TestOnePage extends StatelessWidget {
  final logic = Get.put(TestOneLogic());

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
  • logic
<code class="dart">class TestOneLogic extends GetxController {

}

Binding:须要配套GetX路由

  • binding
<code class="dart">class TestTwoBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(() => TestTwoLogic());
  }
}
  • view
<code class="dart">class TestTwoPage extends StatelessWidget {
  final logic = Get.find<TestTwoLogic>();

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
  • logic
<code class="dart">class TestTwoLogic extends GetxController {

}
  • 须要在路由模块绑定下这个binding
<code class="dart">void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: RouteConfig.testOne,
      getPages: RouteConfig.getPages,
    );
  }
}

class RouteConfig {
  static const String testTwo = "/testTwo";

  static final List<GetPage> getPages = [
    GetPage(
      name: testTwo,
      page: () => TestTwoPage(),
      binding: TestTwoBinding(),
    ),
  ];
}

总结

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
<code class="dart">class TestTwoPage extends StatefulWidget {
  @override
  _TestTwoPageState createState() => _TestTwoPageState();
}

class _TestTwoPageState extends State<TestTwoPage> {
  final logic = Get.put(TestTwoLogic());

  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void dispose() {
    Get.delete<TestTwoLogic>();
    super.dispose();
  }
}
  • logic
class TestTwoLogic extends GetxController {

}

下面这种计划,是根本都能解决回收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能够写成空字符:””)
<code class="dart">import 'package:flutter/material.dart';
import 'package:get/get.dart';

/// GetBindWidget can bind GetxController, and when the page is disposed,
/// it can automatically destroy the bound related GetXController
///
///
/// Sample:
///
/// class SampleController extends GetxController {
///   final String title = 'My Awesome View';
/// }
///
/// class SamplePage extends StatelessWidget {
///   final controller = SampleController();
///
///   @override
///   Widget build(BuildContext context) {
///     return GetBindWidget(
///       bind: controller,
///       child: Container(),
///     );
///   }
/// }
class GetBindWidget extends StatefulWidget {
  const GetBindWidget({
    Key? key,
    this.bind,
    this.tag,
    this.binds,
    this.tags,
    required this.child,
  })  : assert(
          binds == null || tags == null || binds.length == tags.length,
          'The binds and tags arrays length should be equal\n'
          'and the elements in the two arrays correspond one-to-one',
        ),
        super(key: key);

  final GetxController? bind;
  final String? tag;

  final List<GetxController>? binds;
  final List<String>? tags;

  final Widget child;

  @override
  _GetBindWidgetState createState() => _GetBindWidgetState();
}

class _GetBindWidgetState extends State<GetBindWidget> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void dispose() {
    _closeGetXController();
    _closeGetXControllers();

    super.dispose();
  }

  ///Close GetxController bound to the current page
  void _closeGetXController() {
    if (widget.bind == null) {
      return;
    }

    var key = widget.bind.runtimeType.toString() + (widget.tag ?? '');
    GetInstance().delete(key: key);
  }

  ///Batch close GetxController bound to the current page
  void _closeGetXControllers() {
    if (widget.binds == null) {
      return;
    }

    for (var i = 0; i < widget.binds!.length; i++) {
      var type = widget.binds![i].runtimeType.toString();

      if (widget.tags == null) {
        GetInstance().delete(key: type);
      } else {
        var key = type + (widget.tags?[i] ?? '');
        GetInstance().delete(key: key);
      }
    }
  }
}
  • 应用十分的简略
<code class="dart">/// 回收单个GetXController
class TestPage extends StatelessWidget {
  final logic = Get.put(TestLogic());

  @override
  Widget build(BuildContext context) {
    return GetBindWidget(
      bind: logic,
      child: Container(),
    );
  }
}

/// 回收多个GetXController
class TestPage extends StatelessWidget {
  final logicOne = Get.put(TestLogic(), tag: 'one');
  final logicTwo = Get.put(TestLogic());
  final logicThree = Get.put(TestLogic(), tag: 'three');

  @override
  Widget build(BuildContext context) {
    return GetBindWidget(
      binds: [logicOne, logicTwo, logicThree],
      tags: ['one', '', 'three'],
      child: Container(),
    );
  }
}

/// 回收日志
[GETX] Instance "TestLogic" has been created with tag "one"
[GETX] Instance "TestLogic" with tag "one" has been initialized
[GETX] Instance "TestLogic" has been created
[GETX] Instance "TestLogic" has been initialized
[GETX] Instance "TestLogic" has been created with tag "three"
[GETX] Instance "TestLogic" with tag "three" has been initialized
[GETX] "TestLogicone" onDelete() called
[GETX] "TestLogicone" deleted from memory
[GETX] "TestLogic" onDelete() called
[GETX] "TestLogic" deleted from memory
[GETX] "TestLogicthree" onDelete() called
[GETX] "TestLogicthree" deleted from memory

总结

对于下面的优化计划

  • 就算你不应用GetX路由,你也能够很轻松的回收对应的GetXController了
  • 这种回收形式在GetBuilder和Obx俩种刷新机制中,都是通用的
  • 回收的机会:是以后页面被回收的时候

惟一麻烦的:须要你手动把GetBindWidget这个控件,引入到本人的我的项目中

LintNorm

这个性能,乍一看,大家预计都懵逼了;这要不是我写的,我看了也懵逼啊

然而,这个性能,真是少部分强迫症患者的福音

因为getx作者,在demo我的项目外面,引入的lint库,一些小伙伴可能也用了这个库

lint(pub):https://pub.dev/packages/lint

lint是一个严格规定的代码库,对于代码相应不标准的中央,会通过IDEA给与提醒;对于咱们很多认为正当的代码,有时候可能也会给出相应的正告

  • 在生成的模板代码,有几行就会在lint规定下被正告

    • 这俩个注入代码,都会主动推导出对应的类型;然而在lint规定下,会有黄色下划线正告
  • 须要做这样的调整,能力去掉正告

选中lintNorm按钮,就会以上面这种模式生成模板代码;所以说这个性能是强迫症患者福音。。。

对于用lint这种强规定的人,我示意:

通用后缀批改

  • 反对通用后缀名批改

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.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;提之前:请先思考下,合不合理

最初

在不断完善这个插件的时候,也是我一直思考的一个过程,

感激大家提的各种蛋痛的需要

能让这个插件一点点的欠缺,以至于当初,,能真正的帮忙靓仔们节俭一点开发工夫

系列文章 + 相干地址

  • 插件的Github地址:getx_template
  • Flutter GetX应用—简洁的魅力!
  • Flutter GetX深度分析 | 咱们终将走出本人的路(万字图文)

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:GetX代码生成IDEA插件超详细功能讲解透过现象看本质

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址