修复Flutter官方Slider bug并成功合入的经历
介绍
如果你在开发的过程中发现无论怎么调试结果都不符合预期,你会怎么办?怀疑自己功力不够,还是查看源码,分析原因。下面我来讲述一下我在一个项目开发中碰到Flutter官方问题,以及最后的处理。
- 我给flutter的代码仓库提的issue
- 修复完后合入到Flutter官方代码库的Pull Request
Flutter安排的的code review,第一次见识优秀项目做code review是多么的细致,包括注释的错别字问题,代码的缩进等
发现问题
前一阵参与开源项目中tdesign-flutter中Slider滑块选择器的开发,前面在做单滑块的时候还比较顺利。然后在做RangeSlider的时候发现了问题,当我把overlayShape设置为SliderComponentShape.noOverlay(也就是长按时不需要绘制滑块的浮层)的时候,发现RangeSlider的左右两侧的边距处理的不太正常,滑块都绘制到了布局外面,而Slider则表现的是正常的。
示例代码
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.
);
}
}
定位问题
继续看到它的paint方法
这里很清楚了,我们直接去看这个trackRect的获取方法getPreferredRect
这里发现在计算left的时候,值考虑了overlay的宽度,却并没有考虑thumb,也就是滑块的宽度。我们可以对比下Slider中RoundedRectSliderTrackShape的实现。
在Slider中,把trackShape的getPreferredRect抽取到了BaseSliderTrackShape中,毕竟以后定制各种trackShap都可以服用嘛,最关键的是trackLeft考虑了thumbWidth的值
而slider整体的尺寸是和各个shape有关的
到这里我们就已经找到问题了,问题也就好解决了
解决问题
- 参考Slider中抽取的BaseSliderTrackShape,我们在RangeSlider也可以进行抽取BaseRangeSliderTrackShape
- 修复trackLeft的计算
- 删除RoundedRectRangeSliderTrackShape中getPreferredRect的实现,并 with BaseRangeSliderTrackShape,另外其他继承RangeSliderTrackShape的官方实现都要修改
记得写单测
不写单测,flutter的PR检查就过不了的哦
后记
其实大家可以发现这个bug其实很小,也很容易改,但整个过程在参与开源社区中真的可以学到很多东西,如优秀项目的开发合入流程,第一次我只是简单的修改,然后PR的自动化检测就没有通过,包括代码格式问题,没有写单测的问题。在提PR后,总共有三个人来进行code review。他们cr真的非常细致,小到代码锁进格式,注释的瑕疵,而且他们对于写的比较好的地方也会指出来,值得我们学习
转载自:https://juejin.cn/post/7237115019276091453