Flutter使您可以创建精美的本地编译应用程序。Flutter之所以能够做到这一点,是因为Flutter喜欢Material。Material是一个设计系统,可帮助构建高质量的数字体验。随着UI设计的不断发展,Material继续更新其组件,运动和设计系统。
Flutter最近将Slider
和RangeSlider
小部件更新为最新的设计。新的滑块在设计时考虑到了更好的可访问性:轨道更高,拇指带有阴影,并且值指示器具有新的形状和改进的文本缩放支持。
本文介绍了Slider
和RangeSlider
小部件的更改。
更新的内容
Slider
并RangeSlider
进行了更新,以便在使用这些小部件时获得更流畅的体验。此图演示了制作滑块小部件的五个不同组件。
Slider
并RangeSlider
包括五个部分:
- 显示拇指值标签的价值指标
- 拇指滑过的轨迹
- 指示值位置的拇指
- 按下拇指时显示的叠加层
- 滑块不连续时在轨道上的刻度线
注意:本文涉及两种不同类型的叠加层:
- 该
OverlaySlider
组件表示前述图像中提到的组分。 - Flutter的
Overlay
类用于在以下屏幕上显示的所有其他小部件上“浮动”小部件。
新的默认值指标形状
旧滑块和新滑块小部件之间最大的视觉差异是默认值指示符:RectangularSliderValueIndicatorShape
for Slider
和RectangularRangeSliderValueIndicatorShape
for RangeSlider
。指标反映了Material的最新设计更改。旧的指示器形状是一个颠倒的梨,新的指示器形状更加矩形,看起来像气泡。值指标进行了两个更新Slider
和RangeSlider
。
value指标画在覆盖层上
现在,更新后的值指示符已绘制在叠加层上。这意味着该指示符不再局限于滑块的范围,而是MediaQuery
可以显示在其他窗口小部件上。这是预料之中的,因为只有在处理手势检测器时才激活指示器,这意味着仅在用户与滑块交互时才显示指示器。通过将,,和小部件集成Overlay
在一起CompositedTransformTarget
,值指示器可以显示在其他小部件上方。要了解有关此机制的更多信息,请参见如何在(可能是经过转换的)UI小部件上浮动覆盖小部件。CompositedTransformFollower
Layerlink
下图显示了Slider
和RangeSlider
窗口小部件的制作方式:
您可能会注意到,我们使用单独LeafRenderObjectWidget
的标记在叠加层上绘制指示器。这是因为我们需要在Overlay
类和屏幕上都进行绘制,而您不能在同一个LeafRenderObjectWidget
窗口小部件上进行绘制。
因为我们现在在覆盖层上绘制值指示符,所以它不再局限于MediaQuery
包含滑块的范围。该指示器不再被剪切到该框,这意味着始终显示整个值指示器。
注意:此示例的textScaleFactor
设置为4,以进行更好的演示。
值指示器矩形已移动,因此指示器的一部分不会离开屏幕。这项改进使您可以增加指示器内的位数并增加应用程序的文本比例因子,而不必担心文本是否超出屏幕尺寸。在下图中,值指示符文本比例为4,并且包含3位数字的值,但是滑块可以毫无问题地处理它。
double getHorizontalShift({ RenderBox parentBox, Offset center, TextPainter labelPainter, double textScaleFactor, Size sizeWithOverflow, double scale,}) { assert(!sizeWithOverflow.isEmpty); const double edgePadding = 8.0; final double rectangleWidth = _upperRectangleWidth(labelPainter, scale, textScaleFactor); /// Value indicator draws on the overlay, and by using the global Offset, /// we are making sure that we use the bounds of the Overlay instead of the Slider. final Offset globalCenter = parentBox.localToGlobal(center); // The rectangle must be shifted toward the center so that it minimizes the // chance of it rendering outside the bounds of the render box. If the shift // is negative, then the lobe is shifted from right to left. If the shift is // positive, then the lobe is shifted from left to right. final double overflowLeft = math.max(0, rectangleWidth / 2 — globalCenter.dx + edgePadding); final double overflowRight = math.max(0, rectangleWidth / 2 — (sizeWithOverflow.width — globalCenter.dx — edgePadding)); if (rectangleWidth < sizeWithOverflow.width) { return overflowLeft — overflowRight; } else if (overflowLeft — overflowRight > 0) { return overflowLeft — (edgePadding * textScaleFactor); } else { return -overflowRight + (edgePadding * textScaleFactor); }}
设置值指示器优先
的RangeSlider
值指示器也更新,使得当前活动的指示器优先于静止指示器。这意味着,如果指标重叠,则活动指标在另一指标上方“浮动”。
注意:此示例的textScaleFactor
设置为4,以进行更好的演示。
旧值指标已更新
我们保留了PaddleValueIndicator
小部件,并对其进行了更新以具有更好的可伸缩性和可访问性。该PaddleValueIndicator
插件也印刷在Overlay
喜欢的RectangularSliderValueIndicatorShape
。在以下示例中,您可以看到Slider
和RangeSlider
都在使用旧值指示器。如果您想继续使用旧的值指示符,则只需用包裹Slider
小部件SliderTheme
,然后将valueIndicatorShape
属性设置为SliderThemeData
即可PaddleSliderValueIndicatorShape
。的过程是相同的RangeSlider
。用包裹RangeSlider
小部件SliderTheme
,然后将rangeValueIndicatorShape
属性设置SliderThemeData
为PaddleRangeSliderValueIndicatorShape
。
活动轨道大于非活动轨道
其他组件的形状Slider
也已更新。更改了轨道形状,以使轨道的活动部分大于轨道的非活动部分。这意味着,如果您的应用程序使用从左到右的语言,则轨道的左侧部分大于右侧。如果您的应用程序使用从右到左的语言,则曲目的右侧部分大于左侧。对于RangeSlider
,活动轨道是两个拇指之间的轨道部分。
刻度线组件
刻度线的大小和位置已更改。刻度线现在是轨道组件的一部分,而不是延伸轨道的末端。刻度线上也有填充,因此它出现在跟踪组件中。刻度线的大小现在的半径为1。
拇指组件有阴影
激活拇指滑块组件后,上会Shadow
出现一个Overlay
。