介绍

假如你在开发的过程中发现无论怎么调试结果都不契合预期,你会怎么办?置疑自己功力不够,仍是检查源码,剖析原因。下面我来叙述一下我在一个项目开发中碰到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滑动选择器,附源码中介绍了Slider的定制流程,这儿就不再赘述。)

修复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真的非常细致,小到代码锁进格式,注释的瑕疵,而且他们关于写的比较好的当地也会指出来,值得咱们学习