gpt4 book ai didi

flutter - 如何在 Flutter 中圆滑 slider 的角

转载 作者:IT王子 更新时间:2023-10-29 07:07:35 27 4
gpt4 key购买 nike

我使用的是基本 slider ,我发现了如何只更新 slider 主题数据中我想更改的部分,例如 trackHeight,但不幸的是,我不确定如何更新“trackShape”字段。以下是我在主应用程序中更新轨道高度的操作,例如:

final SliderThemeData tweakedSliderTheme = Theme.of(context).sliderTheme.copyWith(
trackHeight: 22.0,
//trackShape: RectangularSliderTrackShape(), // How do I update this??
);

我确实尝试使用 ClipRRect() slider 小部件周围没有任何效果。

这是一个 slider 的简单页面:

import 'package:flutter/material.dart';

class RoomControl extends StatefulWidget {
@override
_RoomControlState createState() => _RoomControlState();
}

class _RoomControlState extends State<RoomControl> {
double _value = 0.0;
void _setvalue(double value) => setState(() => _value = value);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Name here'),
),
//hit Ctrl+space in intellij to know what are the options you can use in flutter widgets
body: Container(
padding: EdgeInsets.all(32.0),
child: Center(
child: Column(
children: <Widget>[
Text('Value: ${(_value * 100).round()}'),
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child:Slider(
value: _value,
onChanged: _setvalue,
divisions: 10,
)
)
],
),
),
),
);
}
}

这是 slider 的样子:

enter image description here

更新:得到答案后,我可以通过更新刻度线形状和拇指形状轻松创建类似这样的东西:

enter image description here

final SliderThemeData tweakedSliderTheme = Theme.of(context).sliderTheme.copyWith(
trackHeight: 20.0,
thumbShape: MyRoundSliderThumbShape(enabledThumbRadius: 13.0, disabledThumbRadius: 13.0),
trackShape: MyRoundSliderTrackShape(), // TODO: this is hard coded right now for 20 track height
inactiveTrackColor: lightGreySliderColor,
activeTickMarkColor: Color(blackPrimaryValue),
inactiveTickMarkColor: colorizedMenuColor,
tickMarkShape: MyRectSliderTickMarkShape(tickMarkRadius: 4.0),
);

刻度线的形状有一点小技巧。如果你把它做得太大,它就会跳过绘画!可能是有道理的,但我对绘画/渲染知之甚少,所以我花了一段时间才学会如何让刻度线 (Rect) 正确显示

最佳答案

Image of Slider with Rounded Corners我已将基本代码从 RectangularSliderTrackShape 复制到一个名为 RoundSliderTrackShape 的新类中。

round_slider_track_shape.dart

import 'dart:math';
import 'package:flutter/material.dart';

class RoundSliderTrackShape extends SliderTrackShape {
/// Create a slider track that draws 2 rectangles.
const RoundSliderTrackShape({ this.disabledThumbGapWidth = 2.0 });

/// Horizontal spacing, or gap, between the disabled thumb and the track.
///
/// This is only used when the slider is disabled. There is no gap around
/// the thumb and any part of the track when the slider is enabled. The
/// Material spec defaults this gap width 2, which is half of the disabled
/// thumb radius.
final double disabledThumbGapWidth;

@override
Rect getPreferredRect({
RenderBox parentBox,
Offset offset = Offset.zero,
SliderThemeData sliderTheme,
bool isEnabled,
bool isDiscrete,
}) {
final double overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
final double trackHeight = sliderTheme.trackHeight;
assert(overlayWidth >= 0);
assert(trackHeight >= 0);
assert(parentBox.size.width >= overlayWidth);
assert(parentBox.size.height >= trackHeight);

final double trackLeft = offset.dx + overlayWidth / 2;
final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
// TODO(clocksmith): Although this works for a material, perhaps the default
// rectangular track should be padded not just by the overlay, but by the
// max of the thumb and the overlay, in case there is no overlay.
final double trackWidth = parentBox.size.width - overlayWidth;
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
}


@override
void paint(
PaintingContext context,
Offset offset, {
RenderBox parentBox,
SliderThemeData sliderTheme,
Animation<double> enableAnimation,
TextDirection textDirection,
Offset thumbCenter,
bool isDiscrete,
bool isEnabled,
}) {
// If the slider track height is 0, then it makes no difference whether the
// track is painted or not, therefore the painting can be a no-op.
if (sliderTheme.trackHeight == 0) {
return;
}

// Assign the track segment paints, which are left: active, right: inactive,
// but reversed for right to left text.
final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor , end: sliderTheme.activeTrackColor);
final ColorTween inactiveTrackColorTween = ColorTween(begin: sliderTheme.disabledInactiveTrackColor , end: sliderTheme.inactiveTrackColor);
final Paint activePaint = Paint()..color = activeTrackColorTween.evaluate(enableAnimation);
final Paint inactivePaint = Paint()..color = inactiveTrackColorTween.evaluate(enableAnimation);
Paint leftTrackPaint;
Paint rightTrackPaint;
switch (textDirection) {
case TextDirection.ltr:
leftTrackPaint = activePaint;
rightTrackPaint = inactivePaint;
break;
case TextDirection.rtl:
leftTrackPaint = inactivePaint;
rightTrackPaint = activePaint;
break;
}

// Used to create a gap around the thumb iff the slider is disabled.
// If the slider is enabled, the track can be drawn beneath the thumb
// without a gap. But when the slider is disabled, the track is shortened
// and this gap helps determine how much shorter it should be.
// TODO(clocksmith): The new Material spec has a gray circle in place of this gap.
double horizontalAdjustment = 0.0;
if (!isEnabled) {
final double disabledThumbRadius = sliderTheme.thumbShape.getPreferredSize(false, isDiscrete).width / 2.0;
final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
horizontalAdjustment = disabledThumbRadius + gap;
}

final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx - horizontalAdjustment, trackRect.bottom);

// Left Arc
context.canvas.drawArc(
Rect.fromCircle(center: Offset(trackRect.left, trackRect.top + 11.0), radius: 11.0),
-pi * 3 / 2, // -270 degrees
pi, // 180 degrees
false,
trackRect.left - thumbCenter.dx == 0.0 ? rightTrackPaint : leftTrackPaint
);

// Right Arc
context.canvas.drawArc(
Rect.fromCircle(center: Offset(trackRect.right, trackRect.top + 11.0), radius: 11.0),
-pi / 2, // -90 degrees
pi, // 180 degrees
false,
trackRect.right - thumbCenter.dx == 0.0 ? leftTrackPaint : rightTrackPaint
);

context.canvas.drawRect(leftTrackSegment, leftTrackPaint);
final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + horizontalAdjustment, trackRect.top, trackRect.right, trackRect.bottom);
context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
}
}

以下是 SliderTheme 的设置方式。

import 'package:flutter_stackoverflow/round_slider_track_shape.dart';
...
sliderTheme: Theme.of(context).sliderTheme.copyWith(
trackHeight: 22.0,
trackShape: RoundSliderTrackShape(),
activeTrackColor: Colors.green,
// trackShape: RectangularSliderTrackShape(),
),

在SliderTrack的边上增加了两个圆弧

// Left Arc
context.canvas.drawArc(
Rect.fromCircle(center: Offset(trackRect.left, trackRect.top + 11.0), radius: 11.0),
-pi * 3 / 2, // -270 degrees
pi, // 180 degrees
false,
trackRect.left - thumbCenter.dx == 0.0 ? rightTrackPaint : leftTrackPaint
);

// Right Arc
context.canvas.drawArc(
Rect.fromCircle(center: Offset(trackRect.right, trackRect.top + 11.0), radius: 11.0),
-pi / 2, // -90 degrees
pi, // 180 degrees
false,
trackRect.right - thumbCenter.dx == 0.0 ? leftTrackPaint : rightTrackPaint
);

关于flutter - 如何在 Flutter 中圆滑 slider 的角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55987559/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com