【发布时间】:2018-10-05 19:51:15
【问题描述】:
如何禁用 Widget 上的默认飞溅/波纹/墨迹效果?有时效果是不需要的,例如在以下 TextField 情况下:
【问题讨论】:
如何禁用 Widget 上的默认飞溅/波纹/墨迹效果?有时效果是不需要的,例如在以下 TextField 情况下:
【问题讨论】:
根据上面@hunter 的建议,我发现通过将我的主题中的highlightColor 和splashColor 都设置为Colors.transparent 消除了涟漪。
我确实担心设置highlightColor 可能会产生一些连锁反应,但我还没有注意到。
编辑:虽然我最初的答案有很多赞成票,但我学到的越多,我就越意识到这确实不是正确的方法。正如下面几个人所指出的,更好的解决方案是使用splashFactory。例如,下面的代码显示它是直接通过样式设置的,或者您也可以在主题中设置它:
ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
splashFactory: NoSplash.splashFactory,
),
child: child,
);
【讨论】:
highlightColor 设置为透明使得使用Theme.of(context).highlightColor 毫无意义
您可以将组件包装到Theme 中,并将splashColor 和highlightColor 的属性设置为ThemeData 上的透明
Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: YourWidget(),
);
【讨论】:
Theme.of(context).copyWith 而不是ThemeData,因为它将保留已经定义的主题数据而不是flutter的默认数据:)
您可以将主题的splashFactory 替换为不绘制任何内容的主题:
class NoSplashFactory extends InteractiveInkFeatureFactory {
const NoSplashFactory();
@override
InteractiveInkFeature create({
MaterialInkController controller,
RenderBox referenceBox,
Offset position,
Color color,
TextDirection textDirection,
bool containedInkWell = false,
Rect Function() rectCallback,
BorderRadius borderRadius,
ShapeBorder customBorder,
double radius,
VoidCallback onRemoved,
}) {
return NoSplash(
controller: controller,
referenceBox: referenceBox,
);
}
}
class NoSplash extends InteractiveInkFeature {
NoSplash({
@required MaterialInkController controller,
@required RenderBox referenceBox,
}) : assert(controller != null),
assert(referenceBox != null),
super(
controller: controller,
referenceBox: referenceBox,
);
@override
void paintFeature(Canvas canvas, Matrix4 transform) {}
}
并用它包装你的小部件:
child: new Theme(
data: new ThemeData(splashFactory: const NoSplashFactory()),
child: new TextField(...),
),
最初由 HansMuller 在 GitHub PR 上回答。
【讨论】:
ThemeData(splashColor: Colors.transparent)
@override 注解应该被移除,因为InteractiveInkFeatureFactory 是最新版本的flutter中的一个抽象类。
splashFactory: NoSplash.splashFactory
我将修改 Camilo 的方法,以确保我们不会覆盖父主题的其他属性。
var color = Colors.transparent;
Theme(
data: Theme.of(context).copyWith(
highlightColor: color,
splashColor: color,
hoverColor: color,
),
child: YourWidget(),
)
【讨论】:
设置为主题
final yourTheme = ThemeData.light();
...
Theme(
data: yourTheme.copyWith(
splashFactory: NoSplash.splashFactory,
),
...
)
设置为材质小部件
ElevatedButton(
style: ElevatedButton.styleFrom(
splashFactory: NoSplash.splashFactory,
),
onPressed: () { },
child: Text('No Splash'),
)
【讨论】:
我试过上面的答案没有成功(splashColor: Colors.transparent, highlightColor: Colors.transparent,)。
我的解决方案是只设置hoverColor:Colors.transparent
【讨论】:
当我正在寻找一种从列表过度滚动中删除斜线的方法时,没有一个与 ThemeData 相关的解决方案对我有用。我认为这个问题与我的问题相同,因此对于面临相同误解的任何用户,以下解决方案被证明是有效的,并且在放入无状态小部件时非常简洁,如下所示:
class NoSplash extends StatelessWidget {
NoSplash({this.child});
final Widget child;
@override
Widget build(BuildContext context) {
return NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
return true;
},
child: child);
}
}
使用它的方法是简单地用 NoSplash(child: ) 包装你的小部件
希望有人觉得这很有用!
【讨论】: