Flutter Custom Widgets & Animations: The Complete Guide to Mastering UI

Flutter Custom Widgets & Animations: The Complete Guide to Mastering UI

FlutterPulse

This article was translated specially for the channel FlutterPulseYou'll find lots of interesting things related to Flutter on this channel. Don't hesitate to subscribe!🚀

Customizing Widgets and Animations in Flutter with Example

Customizing Widgets and Animations in Flutter with Example

🚀Supercharge Your UI: Customizing Widgets and Animations in Flutter (With Code Examples)

Flutter is famous for its "everything's a widget" approach. While the Material and Cupertino widget libraries are vast, Flutter's true power lies in your ability to create custom widgets and design unique animations that differentiate your app.

Learning to customize these building blocks is essential for any developer who aspires to build professional and memorable user interfaces (UIs).

You can read this full story by clicking here!!

Parte 1:Creating Custom Widgets (The Building Block)

A custom widget is simply an encapsulation of one or more pre-existing widgets. This improves code reuse, readability, and makes your application easier to maintain.

🧱 Example: A Reusable Profile Button (ProfileButton)

Instead of building a Row with a CircleAvatar and aTextEvery time a profile needs to be displayed, we create a custom widget.

Code for profile_button.dart:

import 'package:flutter/material.dart';
class ProfileButton extends StatelessWidget {
// Custom properties defined in the constructor
final String userName;
final String imageUrl;
final VoidCallback onTap;
const ProfileButton({
Key? key,
required this.userName,
required this.imageUrl,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircleAvatar(
backgroundImage: NetworkImage(imageUrl),
radius: 20,
),
const SizedBox(width: 10),
Text(
userName,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}

Use in the application (main.dart):

// ... inside the build() method of a widget
ProfileButton(
userName: 'Alice',
imageUrl: 'https://ejemplo.com/avatar.jpg', // Replace with a real URL
onTap: () {
print('Perfil de Alice pulsado');
},
),

💡 Why is this important?

  • Reusability: Use it ProfileButtonin your sidebar, header, or anywhere else without repeating your design code.
  • Encapsulation: If you decide to change the font or size of your avatar, you only need to modify one file (profile_button.dart).

Parte 2: Custom Animations (Bringing UI to Life)

Animations transform a static UI into a dynamic user experience. Flutter offers two types:

  1. Implicit Animations (Easy): These use widgets like AnimatedContainer, AnimatedOpacity, or AnimatedSize. Simply change a property and the widget animates automatically.
  2. Explicit Animations (Custom): These use AnimationController and Tween for full control over the transition. The AnimatedBuilder widget is the key tool for this.

✨ Example: A Pulsing Container with AnimatedBuilder

We'll create a container that rhythmically changes scale and color, as if it were "pulsing" (useful for status indicators).

codePulsingContainer (requires a StatefulWidget):

import 'package:flutter/material.dart';
class PulsingContainer extends StatefulWidget {
const PulsingContainer({super.key});
@override
State<PulsingContainer> createState() => _PulsingContainerState();
}
class _PulsingContainerState extends State<PulsingContainer>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<Color?> _colorAnimation;
@override
void initState() {
super.initState();
// 1. Initialize the controller for 1 second
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1000),
)..repeat(reverse: true); //
// 2. Defines the scale animation (Tween)
_scaleAnimation = Tween<double>(begin: 1.0, end: 1.15).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
);
// 3. Defines the color animation (Tween)
_colorAnimation = ColorTween(
begin: Colors.blue.shade300,
end: Colors.blue.shade700,
).animate(_controller);
}
@override
Widget build(BuildContext context) {
// 4. Use AnimatedBuilder to rebuild just the widget
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.scale(
scale: _scaleAnimation.value,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: _colorAnimation.value, // Color animado
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: _colorAnimation.value!.withOpacity(0.5),
blurRadius: 10,
),
],
),
child: child,
),
);
},
child: const Center(
child: Text('Pulse', style: TextStyle(color: Colors.white)),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}

Use in the application (main.dart):

// ... inside the build() method of a widget
Center(
child: PulsingContainer(),
),

Conclusion

Customizing widgets and animations in Flutter isn't just a way to enhance your UI; it's a fundamental practice for creating clean code architecture and delivering an exceptional user experience. By mastering these techniques, you'll transform your app from a simple functional tool into a polished and engaging digital product.

Report Page