Reputation: 1245
I want to animate the border for my container with a glowing effect in flutter, do you have any idea ?
Upvotes: 9
Views: 18817
Reputation: 747
I found it easiest to use AnimatedContainer
with a Timer
.
Here's a fully working example: https://dartpad.dev/010e8a96bae7cd84375c087cc06c11d3
import 'dart:async';
import 'package:flutter/material.dart';
class AnimatedBorderComponent extends StatefulWidget {
const AnimatedBorderComponent({ super.key });
@override
State<AnimatedBorderComponent> createState() { return _AnimatedBorderComponentState(); }
}
class _AnimatedBorderComponentState extends State<AnimatedBorderComponent> {
int index = 0;
List<Color> colors = [Colors.red, Colors.orange, Colors.yellow, Colors.green, Colors.blue, Colors.purple];
Duration duration = const Duration(milliseconds: 250);
Timer? _timer;
@override
void initState() {
super.initState();
// set up a timer, make state changes, and redraw.
_timer = Timer.periodic(duration, (timer) {
index = (index + 1) % colors.length;
if (mounted) { setState(() {}); }
});
}
@override
void dispose() {
super.dispose();
// make sure to dispose of the timer when you're done.
_timer?.cancel();
}
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: duration,
curve: Curves.easeInOut,
// change whatever properties you want, and the
// AnimatedContainer takes care of the heavy lifting.
decoration: BoxDecoration(
border: Border.all(color: colors[index], style: BorderStyle.solid, width: 4),
),
);
}
}
Upvotes: 3
Reputation: 11
If you use a State Management package in your app such Get
, Provider
, etc., you may listen to AnimationContiner
with a bool
that you can provide.
Let's say that you have a bool
variable called isEmptyError
, this would look like
final isEmptyError = false.obs;
Obx(
() => AnimatedContainer(
duration: const Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
decoration: BoxDecoration(
border: Border.all(
color: Get.theme.primaryColor,
width: 6,
style: isEmptyError() ? BorderStyle.solid : BorderStyle.none,
),
),
child: TextButton(
style: ButtonStyle(overlayColor: MaterialStateColor.resolveWith((_) => Colors.transparent)),
child: const Text('Press To Flash'),
onPressed: () {
isEmptyError(true);
Future.delayed(const Duration(milliseconds: 300), () => isEmptyError(false));
Future.delayed(const Duration(milliseconds: 600), () => isEmptyError(true));
Future.delayed(const Duration(milliseconds: 900), () => isEmptyError(false));
},
),
),
),
Upvotes: 1
Reputation: 1245
Thanks to Lakhwinder Singh, I made this code and it does the glowing effect that I asked:
import 'package:flutter/material.dart';
void main() {
runApp(new Test());
}
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> with TickerProviderStateMixin {
AnimationController _resizableController;
static Color colorVariation(int note){
if(note <= 1){
return Colors.blue[50];
}else if(note>1 && note<=2){
return Colors.blue[100];
}else if(note>2 && note<=3){
return Colors.blue[200];
}else if(note>3 && note<=4){
return Colors.blue[300];
}else if(note>4 && note<=5){
return Colors.blue[400];
}else if(note>5 && note<=6){
return Colors.blue;
}else if(note>6 && note<=7){
return Colors.blue[600];
}else if(note>7 && note<=8){
return Colors.blue[700];
}else if(note>8 && note<=9){
return Colors.blue[800];
}else if(note>9 && note<=10){
return Colors.blue[900];
}
}
AnimatedBuilder getContainer() {
return new AnimatedBuilder(
animation: _resizableController,
builder: (context, child) {
return Container(
//color: colorVariation((_resizableController.value *100).round()),
padding: EdgeInsets.all(24),
child: Text("SAMPLE"),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(12)),
border: Border.all(
color: colorVariation((_resizableController.value *10).round()), width:10),
),
);
});
}
@override
void initState() {
_resizableController = new AnimationController(
vsync: this,
duration: new Duration(
milliseconds: 500,
),
);
_resizableController.addStatusListener((animationStatus) {
switch (animationStatus) {
case AnimationStatus.completed:
_resizableController.reverse();
break;
case AnimationStatus.dismissed:
_resizableController.forward();
break;
case AnimationStatus.forward:
break;
case AnimationStatus.reverse:
break;
}
});
_resizableController.forward();
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home:Scaffold(
backgroundColor: Colors.white,
body: Center(child: getContainer())));
}
}
Upvotes: 5
Reputation: 7209
Below code will animate the width of the border
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> with TickerProviderStateMixin {
AnimationController _resizableController;
AnimatedBuilder getContainer() {
return new AnimatedBuilder(
animation: _resizableController,
builder: (context, child) {
return Container(
padding: EdgeInsets.all(24),
child: Text("SAMPLE"),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(12)),
border: Border.all(
color: Colors.blue, width: _resizableController.value * 10),
),
);
});
}
@override
void initState() {
_resizableController = new AnimationController(
vsync: this,
duration: new Duration(
milliseconds: 1000,
),
);
_resizableController.addStatusListener((animationStatus) {
switch (animationStatus) {
case AnimationStatus.completed:
_resizableController.reverse();
break;
case AnimationStatus.dismissed:
_resizableController.forward();
break;
case AnimationStatus.forward:
break;
case AnimationStatus.reverse:
break;
}
});
_resizableController.forward();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Test"),
centerTitle: true,
),
body: Center(child: getContainer()));
}
}
Upvotes: 13