我有一个按钮小部件,我想运行闪光效果,例如使用 shimmer 和 visibility_ detector 包(我没有设置这些)。这个想法是,每次按钮变得可见时,它都会变得有点引人注目。我使用一个简单的有状态小部件和一个
Future.delayed
函数。每次小部件变得可见时,我的实现都会运行我的 _startShimmer
。但它不闪烁。
有人做过类似的事情吗?我怀疑 shimmer 包有自己的状态,当您将
loop
设置为 1 时,即使 enabled
设置为 true,它也不会重新激活。我还尝试将 loop
设置为 0(这意味着它无限循环),但这没有帮助。
class CTAWidget extends StatefulWidget {
const CTAWidget({Key? key}) : super(key: key);
@override
CTAWidgetState createState() => CTAWidgetState();
}
class CTAWidgetState extends State<CTAWidget>
with WidgetsBindingObserver {
bool _shimmer = false;
@override
void initState() {
super.initState();
_startShimmer();
}
void _startShimmer() {
Future.delayed(const Duration(seconds: 1), () {
if (mounted) {
setState(() {
_shimmer = true;
});
}
});
}
@override
Widget build(BuildContext context) {
return VisibilityDetector(
key: const Key('cta_widget'),
onVisibilityChanged: (VisibilityInfo info) {
// Start shimmer effect when the widget is fully visible
if (info.visibleFraction == 1) {
_startShimmer();
}
},
child: Stack(
children: [
// Shimmer effect
Shimmer.fromColors(
baseColor: AppColors.yellow500,
highlightColor: AppColors.yellow100,
enabled: _shimmer,
loop: 1,
child: Container(
width: double.infinity,
height: 56,
padding: const EdgeInsets.all(16),
decoration: ShapeDecoration(
color: AppColors.yellow500,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
),
),
// Button content
Container(
// My actual button
),
],
),
)
}
}
您需要将
_shimmer
的默认值设置为 true
并在延迟一段时间后将其变为 false
并设置更长的延迟以查看所有微光的动画步骤,请尝试以下操作:
class CTAWidget extends StatefulWidget {
const CTAWidget({Key? key}) : super(key: key);
@override
CTAWidgetState createState() => CTAWidgetState();
}
class CTAWidgetState extends State<CTAWidget> with WidgetsBindingObserver {
bool _shimmer = true;
@override
void initState() {
super.initState();
_startShimmer();
}
void _startShimmer() {
Future.delayed(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
_shimmer = false;
});
}
});
}
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.yellow,
highlightColor: Colors.black26,
enabled: _shimmer,
loop: 1,
child: Container(
width: double.infinity,
height: 56,
padding: const EdgeInsets.all(16),
decoration: ShapeDecoration(
color: Colors.yellow,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
),
);
}
}