iOS 技巧flutter

flutter 使用问题

2022-06-20  本文已影响0人  问题饿
1.在使用Textfield中遇到的问题

flutter中的onchange方法和oc中的textField:(UITextField *)textField shouldChangeCharactersInRange:方法的不同
onchange方法中调用刷新方法的时候,会导致循环进入方法中,光标乱闪

///对当前的TextField下的controller监听去刷视图
_controller.addListener(() {
      setState(() {});
    });


TextField(
                    controller: _controller,
                    focusNode: _focusNode,
                    textInputAction: TextInputAction.search,
                    style: TextStyle(fontSize: 17, color: Colours.text),
                    maxLines: 1,
                    cursorColor: Colours.app_main,
                    textCapitalization: TextCapitalization.characters,
                    inputFormatters: [
                      LengthLimitingTextInputFormatter(21),
                      FilteringTextInputFormatter.allow(RegExp('[a-z0-9A-Z ]')),
                    ],
                    decoration: InputDecoration(
                        border: InputBorder.none,
                        hintText: '请输入VIN码或点击图片上传',
                      ///这个右侧一键清除的按钮,不随着文字是否存在变动
                        suffixIcon: _controller.text.isNotEmpty
                            ? IconButton(
                                icon: Icon(IconFont.guanbi,
                                    size: 15, color: Color(0x66000000)),
                                onPressed: () => _controller.clear())
                            : null),
                    onChanged: (value) {
                      ///这边onchangge的方法,和oc中的输入监听不同,oc中的监听是实时监听,输入前,这个是后
                      var formateValue = _viewModel.getFormateVinCode(value);

                      if (formateValue.length % 4 == 0) {
                        var _newtext = _controller.text + ' ';

                        _controller.value = TextEditingValue(
                            text: _newtext,
                            selection: TextSelection.fromPosition(TextPosition(
                                affinity: TextAffinity.downstream,
                                offset: _newtext.length)));
                      }
                    },
                    onSubmitted: (value) {
                      do some thing...
                    },
                  ),
2.wrap空间包含row问题

Warp流控件中child中包含row控件的时候,要使用MainAxisSize.min的
wrap流式布局的时候,里面使用了row进行自适应的时候,要采用上述的属性,不然wrap中每行都会充满,
官方注释:

  /// Minimize the amount of free space along the main axis, subject to the
  /// incoming layout constraints.
  ///
  /// If the incoming layout constraints have a large enough
  /// [BoxConstraints.minWidth] or [BoxConstraints.minHeight], there might still
  /// be a non-zero amount of free space.
  ///
  /// If the incoming layout constraints are unbounded, and any children have a
  /// non-zero [FlexParentData.flex] and a [FlexFit.tight] fit (as applied by
  /// [Expanded]), the [RenderFlex] will assert, because there would be infinite
  /// remaining free space and boxes cannot be given infinite size.
//最小化沿主轴的空闲空间,取决于
//输入布局约束。
///如果传入的布局约束有足够大
/ / / [BoxConstraints。minWidth]或[BoxConstraints。可能还会有
///是一个非零的空闲空间。
///如果传入的布局约束是无界的,并且任何子元素都有
/ / /非零(FlexParentData。和一个[FlexFit. flex]。配合(如应用于
/// [Expanded]), [RenderFlex]将断言,因为会有无限
///剩余的空闲空间和盒子不能被赋予无限的大小。

wrap中每个只有在边界的时候有个强力约束,每个item没有强约束,所以导致在wrap中使用row控件的时候,row控件会沾满整个wrap控件的一行,充满了item的导致,设置min使其最小化空间约束,根据自控件的内容来进行最小布局约束。

3.Flutter 标签字体下沉Bug
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 3,vertical: 1),
      decoration: BoxDecoration(
          color: widget.tagBackGroundColor,
          borderRadius: BorderRadius.circular(3)),
      child: Text(
        widget.tagString,
        textAlign: TextAlign.center,
        style: TextStyle(color: widget.tagTextColor, fontSize: 10),
      ),
    );
  }

测试阶段发现,标签在不同的机器上,标签的样式都不一样。如果什么都不设置就会导致字体偏下。基于之前的React开发经验,基本可以确定是字体行高导致的问题。但是Flutter Text组件没有直接设置行高的地方,这就比较蛋疼,后来询问牛梦林,之前超人那边遇到过这种问题,只需Text设置strutStyle,指定fontSize和外层style设置的字体一致、设置合适的height即可,height值为14/10的值。

      child: Text(
        widget.tagString,
        textAlign: TextAlign.center,
        strutStyle: StrutStyle(fontSize: 10,height: 1.4),
        style: TextStyle(color: widget.tagTextColor, fontSize: 10),
      ),

为什么height设置为1.4,因为默认fontSize为14,标签使用字体值为10,height默认放大1.4倍。

  /// The size of text (in logical pixels) to use when obtaining metrics from the font.
  ///
  /// The [fontSize] is used to get the base set of metrics that are then used to calculated
  /// the metrics of strut. The height and leading are expressed as a multiple of
  /// [fontSize].
  ///
  /// The default fontSize is 14 logical pixels.
  final double? fontSize;
4.Flutter鸿蒙字体被截问题

视觉反馈这个页面的时间字体被截,但是我的机器上都是好的,测试机器也是好的,然后我让视觉把测试机拿过来现场调试,发现是鸿蒙系统。后来慢慢排查,找到了解决方案,只需给包裹Text的外层容器设置一层白色背景即可。

5.Flutter长数字字母省略的显示问题

期望展示效果,单号位置,超出宽度末尾...省略展示
通常做法对Text设置overflow:

overflow: TextOverflow.ellipsis

但以上属性的缺陷是,当遇到长数字,长字母时,会被整体省略:
利用零宽空格字符处理这个问题:

///插入零宽空格字符
  String breakWord(String word) {
    if (word == null || word.isEmpty) {
      return word;
    }
    var breakWord = ' ';
    word.runes.forEach((element) {
      breakWord += String.fromCharCode(element);
      breakWord += '\u200B';
    });
    return breakWord;
  }


text: breakWord(value),

另一种写法

text: value.replaceAll('', '\u200B')

两种写法,在实际展示样式上,视觉显示宽度略有差异。
此外,第二种写法,用replaceAll在处理包含emoji的字符串时会出现not utf-16的问题。

看情况使用以上两种方式处理即可。

6.Flutter中设置图片宽高失效问题

如下代码,发现设置图片宽高无效

Container(
  width: 30,
  height: 30,
  decoration: BoxDecoration(
    color: ThemeColors.halfTranslucent,
    borderRadius: BorderRadius.circular(15)),
  child: LoadAssetImage("ic_back",width: 24,height: 24,)
)

解决方案:在LoadAssetImage前再包一层即可生效

Container(
  width: 30,
  height: 30,
  decoration: BoxDecoration(
    color: ThemeColors.halfTranslucent,
    borderRadius: BorderRadius.circular(15)),
  child: Center(
    child: LoadAssetImage("ic_back",width: 24,height: 24,),
  ),
)
7.Flutter中double精度问题

背景:由于 Dart 使用了和js一样的 IEEE 754 双精度标准进行存储,所以存在和JS一样的精度计算问题

解决方案:采用decimal这个三方库解决
  #解决精度问题
  decimal: 0.3.5
refundAmount =
  "${Decimal.parse("$amountDesc") * Decimal.parse("$refundNumber")}";
8.键盘遮挡问题

1.存在在输入文字的时候,若不选择选择文字预览文字情况下,直接点击拍照,会导致在拍照界面出现键盘,无法进行收起

2.移动开单2.0侧筛界面,当选择确认按钮的时候,一直点击,会导致pop页面多次的情况,导致界面进行多次返回的情况。

原因:

1.该情况,在做收起键盘的操作的时候,未点击预览文字时,直接跳转下个界面的时候,会导致键盘没有完全收起来,同时下面收起键盘的方法的时候,虽然收起了键盘,但是光标仍然存在。

SystemChannels.textInput.invokeMethod('TextInput.hide');

2.侧边页面出现的时候,一直点击确定按钮的时候,会调多次pop方法,会导致关闭抽屉栏页面后,页面还会存在调用一个pop的问题,导致会产生返回上一个界面的问题。

解决

1.使用该方法,收起键盘的同时收起光标,在空白,滑动,点击弹框的时候均收起键盘

FocusScope.of(context).requestFocus(FocusNode());

2.在点击确定的时候,增加标志位,在页面销毁之前,只会调用一次。


1655715619775.jpg

防抖解决方法:

新增到公共库里,支持自定义防抖时间,默认一秒防抖

import 'dart:async';

///按钮防抖,milliseconds防抖时间,默认1秒
Function debounce(Function func, {int milliseconds = 1000}) {
  Timer timer;
  Function target = () {
    if (timer?.isActive ?? false) {
      timer?.cancel();
    }
    timer = Timer(Duration(milliseconds: milliseconds), () {
      func?.call();
    });
  };
  return target;
}

使用

child: GestureDetector(
       onTap: debounce(() {
       print('点击了');
    },milliseconds:1500),
  ),
9.flutter时间格式转换问题

//正常情况下时间格式转字符
var selectedTimeStr =
selectedMonth ?? DateFormat('yyyy-MM').format(DateTime.now());
//可以将时间戳转成对应的字符串

var selectedMonth = '2022-06',

//将字符串转时间戳的时候,正常使用parse方法
var parseTime = DateTime.parse(selectedMonth);

//但是parse只能针对标准格式转化的,比如2022-06这个就无法转,只能转下面标准格式,
//否则会报FormatException错
/// * "2012-02-27"
/// * "2012-02-27 13:27:00"
/// * "2012-02-27 13:27:00.123456789z"
/// * "2012-02-27 13:27:00,123456789z"
/// * "20120227 13:27:00"
/// * "20120227T132700"
/// * "20120227"
/// * "+20120227"
/// * "2012-02-27T14Z"
/// * "2012-02-27T14+00:00"
/// * "-123450101 00:00:00 Z": in the year -12345.
/// * "2002-02-27T14:00:00-0500": Same as "2002-02-27T19:00:00Z"

//使用下面可以解决报错问题,但是无法正确解析,返回的是now的时间格式
var tryParseTime = DateTime.tryParse(selectedMonth) ?? DateTime.now();

//使用下面的可以正常解析
var parseStrictTime = DateFormat('yyyy-MM').parseStrict(selectedMonth);

//parseStrict可以解析任意格式保持统一的,下面的可以解析成2022-01-01 0000000时间

selectedMonth = '2022-';
parseStrictTime =  DateFormat('yyyy-').parseStrict(selectedMonth);
上一篇下一篇

猜你喜欢

热点阅读