Code前端首页关于Code前端联系我们

Flutter整个开发详解:加载实用技巧与陷阱2

terry 2年前 (2023-09-23) 阅读数 63 #移动小程序

1。 Git 包失败

Flutter 项目引用第三方库时,通常会直接引用第三方插件 pub ,但有时为了安全和保护,我们会选择使用 git 引用,例如: 此时在执行futter包过程中,如果失败,futter包会再次到达。 可能会遇到如下所示的问题:Flutter完整开发实战详解: 实用技巧与填坑二

)和flutter包接收过程中出现问题的消息。下次解压包时,会检测到git目录.pub_cache中的目录已存在,但可能为空等。 flutter 包获取 .掉时出现异常,因此需要删除 .pub_cache 中的 git 和 best then 的异常目录 c.将锁定在项目下,然后重新执行flutter包

win 一般在C:\Users\xxxxxx\AppData\AppData\Roam 下会有一个 git 目录。

mac 目录位于 ~/.pub-cache 文件夹中。

2。 TextEditingController

Flutter完整开发实战详解: 实用技巧与填坑二

如上面代码所示,红线表示如果控制器为空,则分配一个TextEditingController。这样写的结果如下图: 问题: Flutter完整开发实战详解: 实用技巧与填坑二

输入成功后,当键盘弹出时,关闭键盘时输入内容消失! 这是因为向后拉弹出窗口和键盘会启动页面build,并且当 controlcontrol 时,每个指定时间的❀nu TextEditingController 导致 文本字段TextEditingValue 重置。 , 如上图所示,因为如果 TEXFIELD Controller 不为空,则不会对Value进行复制,从而避免此类。问题,如下图,先全局构建TextEditingController,然后给它赋值。如果control为空,则直接输入null,避免每次都构建重构文本编辑器。 Flutter完整开发实战详解: 实用技巧与填坑二

3。 Scrollable

Flutter完整开发实战详解: 实用技巧与填坑二

如上图所示,正如前面第七篇文章中分析的那样,Scrollable通常会在可滚动列表中找到,并且可能会发生。 InheritedWidget,通过它我们可以轻松地在子进程上调用Scrollable相关方法

以下代码可以在Scrollable.of(context)中分离到ListView/GridView中。 控制。?高斯模糊效果。 ?通过使用下图所示的代码,可以快速实现想要的Item的效果: Flutter完整开发实战详解: 实用技巧与填坑二

上图为部分代码。完整的代码可以在scroll_to_index_demo_page2.dart中找到。这主要是为每个元素分配了一个GlobalKey,用它来查找所需的元素框中RenderObjectFlutter完整开发实战详解: 实用技巧与填坑二

,然后使用 localToGlobal item 在这个 ViewPort

用于滚动:Flutter完整开发实战详解: 实用技巧与填坑二

当然还有另一种实现方式,参见详细信息scroll_to_index_demo_page。 dart

6、FindRenderObject

在 Flutter 中,Container Widget❀ 之间存在差异。一般来说:

  • T extSliverListTileListTile主要是渲染等。 RenderObjectElement
  • StatelessWidget / StatefulWidget等都属于容器Widget,其中
内部♽组件ComponentElement

本身不存在渲染对象

根据上一章,我们说过BuildContext的实现是ElementElementb,所以context。 这个操作其实就是ElementfindRenderObject()Flutter完整开发实战详解: 实用技巧与填坑二

如上图所示,findRenderObject的实现最终在renderObjectFlutter完整开发实战详解: 实用技巧与填坑二

renderObject

❙❙❙ 获取renderObject的逻辑很清楚,当遇到ComponentElement时,执行时, element.visitvisits,visits;Flutter完整开发实战详解: 实用技巧与填坑二

RenderObjectElement

您可以在以下代码中看到print(“ $ {globalkey.currentContext.findRenderObject()}}”);最终❙❙enderObjectFlutter完整开发实战详解: 实用技巧与填坑二

Flutter完整开发实战详解: 实用技巧与填坑二

7。行距

Flutter完整开发实战详解: 实用技巧与填坑二

在Flutter应用程序中无法直接设置行距Text。文字的显示效果是下图所示的逻辑构图: Flutter完整开发实战详解: 实用技巧与填坑二

那么我们如何处理行距呢?如下图所示,StrutStyle设置leader,然后用它来计算Ts s。方向位置偏移,因为导轨上下平衡,所以计算后就可以得到所需的行距。 (虽然不能保证100%像素精度,但是你知道其他方法吗?) Flutter完整开发实战详解: 实用技巧与填坑二

还有一点就是你还可以通过本地样式来分享DefaultTextStyle。 。

8。 Builder

Flutter完整开发实战详解: 实用技巧与填坑二

Flutter 中有一个类似于 Builder 的 widget。看源码,发现其实就是简单的StatelessWidget的嵌入。那么为什么还需要它呢?

如下图所示,我想一些Flutter开发者在使用Scaffold.of(context).showSnackBar(snackbar)时可能会遇到以下错误。出现这种情况的原因是传入的上下文

是由坏节点导致的,因为这里传递的上下文无法被节点♽ká页面找到位于。 Flutter完整开发实战详解: 实用技巧与填坑二

所以目前Builder的作用就体现出来了。如下图,builder方法返回分配的environment,并成功查找到❙❙❙❙❙❙​​Scaffold父节点。某种程度上,这也体现了ComponentElement的功能之一。 ?

如下图所示,通过嵌套,然后更改,更改❗,定义了transitionBuilder动画效果。 这就是它应该立即动画化的方式。按钮

值可以达到动画变化的效果。 Flutter完整开发实战详解: 实用技巧与填坑二

10。多语言显示异常

官方github.com/flutter/flu...显示Flutter同时显示韩文/日文和中文,导致iOS上文本显示异常。问题,如下图,左侧为异常位置。 Flutter完整开发实战详解: 实用技巧与填坑二

此问题目前有两种解决方案:

  • 添加ttf字体并全局更改字体显示。
  • 更改FontFamilyFallback所有TextTheme通过主题:♿❀Widge tsBinding.instance.window.locale;
获取移动平台本身其目前的语言情况不需要context,设置后也不需要Locale

11。长按输入栏导致的异常

如果您的项目有多语言和主题切换场景,您可能会遇到长按输入栏导致的异常情况。目前推荐两种缓解方法:

  • 1。您可以自定义 ThemeData 固定平台条目,但使用此方法,平台复制和粘贴弹出窗口没有平台属性:
 ///防止输入框长按崩溃问题
platform: TargetPlatform.android
复制代码
  • 2。添加自定义的 LocalizationsDelegate 多语言环境下的自定义支持:


class FallbackCupertinoLocalisationsDelegate
    extends LocalizationsDelegate<CupertinoLocalizations> {
  const FallbackCupertinoLocalisationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) => loadCupertinoLocalizations(locale);

  @override
  bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
}

class CustomZhCupertinoLocalizations extends DefaultCupertinoLocalizations {
  const CustomZhCupertinoLocalizations();

  @override
  String datePickerMinuteSemanticsLabel(int minute) {
    if (minute == 1) return '1 分钟';
    return minute.toString() + ' 分钟';
  }

  @override
  String get anteMeridiemAbbreviation => '上午';

  @override
  String get postMeridiemAbbreviation => '下午';

  @override
  String get alertDialogLabel => '警告';

  @override
  String timerPickerHourLabel(int hour) => '小时';

  @override
  String timerPickerMinuteLabel(int minute) => '分';

  @override
  String timerPickerSecond(int second) => '秒';

  @override
  String get cutButtonLabel => '裁剪';

  @override
  String get copyButtonLabel => '复制';

  @override
  String get pasteButtonLabel => '粘贴';

  @override
  String get selectAllButtonLabel => '全选';
}

class CustomTCCupertinoLocalizations extends DefaultCupertinoLocalizations {
  const CustomTCCupertinoLocalizations();

  @override
  String datePickerMinuteSemanticsLabel(int minute) {
    if (minute == 1) return '1 分鐘';
    return minute.toString() + ' 分鐘';
  }

  @override
  String get anteMeridiemAbbreviation => '上午';

  @override
  String get postMeridiemAbbreviation => '下午';

  @override
  String get alertDialogLabel => '警告';

  @override
  String timerPickerHourLabel(int hour) => '小时';

  @override
  String timerPickerMinuteLabel(int minute) => '分';

  @override
  String timerPickerSecond(int second) => '秒';

  @override
  String get cutButtonLabel => '裁剪';

  @override
  String get copyButtonLabel => '復制';

  @override
  String get pasteButtonLabel => '粘貼';

  @override
  String get selectAllButtonLabel => '全選';
}

Future<CupertinoLocalizations> loadCupertinoLocalizations(Locale locale) {
  CupertinoLocalizations localizations;
  if (locale.languageCode == "zh") {
    switch (locale.countryCode) {
      case 'HK':
      case 'TW':
        localizations = CustomTCCupertinoLocalizations();
        break;
      default:
        localizations = CustomZhCupertinoLocalizations();
    }
  } else {
    localizations = DefaultCupertinoLocalizations();
  }
  return SynchronousFuture<CupertinoLocalizations>(localizations);
}

作者:连毛德小果

链接:https://ju 。 eb9
来源:掘金
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门