Fllutter TabBar中文文字抖动完美解决方案

在使用TabBar当要对当前选中的Label字体变大时,会出现字体抖动的现象。

在其它Flutter文字动画中,只要包含中文,其实都会出现抖动的情况。

先看下效果图:

Fllutter TabBar中文文字抖动完美解决方案

原理:

默认动画是字体的改变,比如从20到40,其实我们可以用Transform的Scale实现的效果,字体从20到40,其实是放大了一倍,相对应的Scale就是从1.0变成2.0,这样就很简单了,动画也就流畅很多了。

操作方法:

复制一份tabs.dart的源代码

找到_TabStyle的build方法,修改以下代码,

Fllutter TabBar中文文字抖动完美解决方案

 

修改return

Fllutter TabBar中文文字抖动完美解决方案

 

_TabStyle源代码(Flutter版本:1.17.2,不同版本的Flutter可能tabs.dart的源代码有所差异,最好按照上面的方法修改):

class _TabStyle extends AnimatedWidget {
  const _TabStyle({
    Key key,
    Animation<double> animation,
    this.selected,
    this.labelColor,
    this.unselectedLabelColor,
    this.labelStyle,
    this.unselectedLabelStyle,
    @required this.child,
  }) : super(key: key, listenable: animation);

  final TextStyle labelStyle;
  final TextStyle unselectedLabelStyle;
  final bool selected;
  final Color labelColor;
  final Color unselectedLabelColor;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final ThemeData themeData = Theme.of(context);
    final TabBarTheme tabBarTheme = TabBarTheme.of(context);
    final Animation<double> animation = listenable as Animation<double>;

    // To enable TextStyle.lerp(style1, style2, value), both styles must have
    // the same value of inherit. Force that to be inherit=true here.

    final TextStyle defaultUnselectedStyle = (unselectedLabelStyle ??
            tabBarTheme.unselectedLabelStyle ??
            labelStyle ??
            themeData.primaryTextTheme.bodyText1)
        .copyWith(inherit: true);
    final TextStyle defaultStyle = (labelStyle ??
            tabBarTheme.labelStyle ??
            themeData.primaryTextTheme.bodyText1)
        .copyWith(inherit: true).copyWith(fontSize:defaultUnselectedStyle.fontSize);
    final TextStyle textStyle = selected
        ? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value)
        : TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value);

    final double multiple = labelStyle.fontSize / unselectedLabelStyle.fontSize;
    final double _scale = selected
        ? lerpDouble(multiple, 1, animation.value)
        : lerpDouble(1, multiple, animation.value);

    final Color selectedColor = labelColor ??
        tabBarTheme.labelColor ??
        themeData.primaryTextTheme.bodyText1.color;
    final Color unselectedColor = unselectedLabelColor ??
        tabBarTheme.unselectedLabelColor ??
        selectedColor.withAlpha(0xB2); // 70% alpha
    final Color color = selected
        ? Color.lerp(selectedColor, unselectedColor, animation.value)
        : Color.lerp(unselectedColor, selectedColor, animation.value);

    return DefaultTextStyle(
      style: textStyle.copyWith(color: color),
      // child: child,
      child: IconTheme.merge(
        data: IconThemeData(
          size: 24.0,
          color: color,
        ),
        child: Transform.scale(scale: _scale, child: child),
      ),
    );
  }
}

引用:

import 'package:CustomTabBar/custom_tab_bar.dart' as Custom;

Custom.TabBar(
                controller: this._controller2,
                indicatorSize: Custom.TabBarIndicatorSize.label,
                indicatorColor: Colors.white,
                labelStyle: TextStyle(
                  fontSize: 18.0,
                  fontWeight: FontWeight.bold,
                ),
                unselectedLabelStyle: TextStyle(fontSize: 15.0),
                indicatorWeight: 3.0,
                isScrollable: true,
                indicatorPadding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 5.0),
                tabs: [
                  Tab(text: '动态'),
                  Tab(text: '热门'),
                  Tab(text: '附近'),
                  Tab(text: '颜值'),
                  Tab(text: '音乐'),
                  Tab(text: '跳舞'),
                ],
              ),

源码地址:https://github.com/terminatorx/CustomTabBar

 

上一篇:tabbar 首页/分类/购物车/我的 组件开发


下一篇:小程序--公共组件