likes
comments
collection
share

修复Flutter官方Slider bug并成功合入的经历

作者站长头像
站长
· 阅读数 33

介绍

如果你在开发的过程中发现无论怎么调试结果都不符合预期,你会怎么办?怀疑自己功力不够,还是查看源码,分析原因。下面我来讲述一下我在一个项目开发中碰到Flutter官方问题,以及最后的处理。

  • 我给flutter的代码仓库提的issue
  • 修复完后合入到Flutter官方代码库的Pull Request

修复Flutter官方Slider bug并成功合入的经历

Flutter安排的的code review,第一次见识优秀项目做code review是多么的细致,包括注释的错别字问题,代码的缩进等

修复Flutter官方Slider bug并成功合入的经历

修复Flutter官方Slider bug并成功合入的经历

发现问题

前一阵参与开源项目中tdesign-flutterSlider滑块选择器的开发,前面在做单滑块的时候还比较顺利。然后在做RangeSlider的时候发现了问题,当我把overlayShape设置为SliderComponentShape.noOverlay(也就是长按时不需要绘制滑块的浮层)的时候,发现RangeSlider的左右两侧的边距处理的不太正常,滑块都绘制到了布局外面,而Slider则表现的是正常的。

修复Flutter官方Slider bug并成功合入的经历

示例代码

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  double singleValue = 0;
  RangeValues rangeValue = RangeValues(0, 10);

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: SliderTheme(
        data: SliderThemeData(
          overlayShape: SliderComponentShape.noOverlay,
        ),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Slider(
                  value: singleValue,
                  min: 0,
                  max: 100,
                  onChanged: (value) {
                    setState(() {
                      singleValue = value;
                    });
                  }),
              RangeSlider(
                  values: rangeValue,
                  min: 0,
                  max: 100,
                  onChanged: (value) {
                    setState(() {
                      rangeValue = value;
                    });
                  })
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

定位问题

修复Flutter官方Slider bug并成功合入的经历

继续看到它的paint方法

修复Flutter官方Slider bug并成功合入的经历

这里很清楚了,我们直接去看这个trackRect的获取方法getPreferredRect

修复Flutter官方Slider bug并成功合入的经历

这里发现在计算left的时候,值考虑了overlay的宽度,却并没有考虑thumb,也就是滑块的宽度。我们可以对比下Slider中RoundedRectSliderTrackShape的实现。

在Slider中,把trackShape的getPreferredRect抽取到了BaseSliderTrackShape中,毕竟以后定制各种trackShap都可以服用嘛,最关键的是trackLeft考虑了thumbWidth的值

修复Flutter官方Slider bug并成功合入的经历

而slider整体的尺寸是和各个shape有关的

修复Flutter官方Slider bug并成功合入的经历

修复Flutter官方Slider bug并成功合入的经历

到这里我们就已经找到问题了,问题也就好解决了

解决问题

  • 参考Slider中抽取的BaseSliderTrackShape,我们在RangeSlider也可以进行抽取BaseRangeSliderTrackShape
  • 修复trackLeft的计算
  • 删除RoundedRectRangeSliderTrackShape中getPreferredRect的实现,并 with BaseRangeSliderTrackShape,另外其他继承RangeSliderTrackShape的官方实现都要修改

修复Flutter官方Slider bug并成功合入的经历

修复Flutter官方Slider bug并成功合入的经历

修复Flutter官方Slider bug并成功合入的经历

记得写单测

不写单测,flutter的PR检查就过不了的哦

修复Flutter官方Slider bug并成功合入的经历

后记

其实大家可以发现这个bug其实很小,也很容易改,但整个过程在参与开源社区中真的可以学到很多东西,如优秀项目的开发合入流程,第一次我只是简单的修改,然后PR的自动化检测就没有通过,包括代码格式问题,没有写单测的问题。在提PR后,总共有三个人来进行code review。他们cr真的非常细致,小到代码锁进格式,注释的瑕疵,而且他们对于写的比较好的地方也会指出来,值得我们学习

转载自:https://juejin.cn/post/7237115019276091453
评论
请登录