Flutter contiene varios tipos de botones incorporados como RaisedButton , FlatButton , etc. Pero con la ayuda de GestureDetector , podemos hacer que cualquier widget realice un conjunto de acciones en ciertos gestos. En este artículo, vamos a usar AnimatedContainer para hacer un botón neumórfico en Flutter. La forma tradicional de crear un botón incluye el uso de sombras paralelas, pero da la sensación de que el botón se desplaza sobre el fondo. Pero en Neumorfismo usamos dos tipos de sombreado: claro en un lado y oscuro en el otro, lo que hace que se sienta como si el botón estuviera pegado al fondo y no flotando sobre él. Usaremos el código VS para desarrollar nuestra aplicación Flutter.
Implementación paso a paso
Paso 1: crear una nueva aplicación de Flutter.
- Abra el código VS y, usando «Ctrl+Shift+P», seleccione «Flutter: New Project».
- Seleccione la carpeta en la que desea crear su aplicación.
- Luego asigne un nombre a su aplicación.
- Después de presionar «Enter», el SDK de Flutter creará un nuevo proyecto para ti.
Paso 2: después de crear el proyecto, abra el archivo «main.dart» y pegue el siguiente código en él.
Dart
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is root // of your application @override Widget build(BuildContext context) { return MaterialApp( // By using this line, // you can hide Debug banner debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const NeumorphismPage(), ); } }
Paso 3: cree un widget con estado debajo del widget MyApp y asígnele el nombre NeumorphismPage. En VS Code, puede intentar escribir «stl» y en autocompletar, seleccione el widget con estado o pegue el código a continuación. Este es el código para el archivo “main.dart”.
Dart
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const NeumorphismPage(), ); } } // Widget that will be shown // at the start of application. class NeumorphismPage extends StatefulWidget { const NeumorphismPage({Key? key}) : super(key: key); @override State<NeumorphismPage> createState() => _NeumorphismPageState(); } class _NeumorphismPageState extends State<NeumorphismPage> { bool _isElevated = false; @override Widget build(BuildContext context) { // Create your widget here. return Scaffold(); } }
Nota: puede crear un archivo dart separado para cada widget y luego importarlo, pero como es solo un widget, solo crearemos un archivo.
Paso 4: El siguiente será el código para crear el botón Neumórfico.
Ejemplo 1
En este ejemplo, después de presionar el botón, se volverá plano.
Dart
class NeumorphismPage extends StatefulWidget { const NeumorphismPage({Key? key}) : super(key: key); @override State<NeumorphismPage> createState() => _NeumorphismPageState(); } class _NeumorphismPageState extends State<NeumorphismPage> { // Boolean to check whether the // button is elevated or not. bool _isElevated = false; @override Widget build(BuildContext context) { return Scaffold( // Providing background // color to our Scaffold backgroundColor: Colors.grey[300], body: Center( // Gesture Detector to detect taps child: GestureDetector( onTap: () { setState(() { _isElevated = !_isElevated; }); }, child: AnimatedContainer( child: Image.asset( "assets/gfg.png", scale: 3, ), // Providing duration parameter // to create animation duration: const Duration( milliseconds: 200, ), height: 200, width: 200, decoration: BoxDecoration( color: Colors.grey[300], shape: BoxShape.circular, // If widget is not elevated, elevate it. boxShadow: _isElevated ? // Elevation Effect [ const BoxShadow( color: Color(0xFFBEBEBE), // Shadow for bottom right corner offset: Offset(10, 10), blurRadius: 30, spreadRadius: 1, ), const BoxShadow( color: Colors.white, // Shadow for top left corner offset: Offset(-10, -10), blurRadius: 30, spreadRadius: 1, ), ] : null, ), ), ), ), ); } }
Producción:
Ejemplo 2
En este widget, después de presionar el botón, se crearán sombras insertadas. Antes de eso, necesitamos agregar un paquete.
flutter pub add flutter_inset_box_shadow
Luego, las importaciones al comienzo del archivo deben cambiarse de la siguiente manera:
import 'package:flutter/material.dart' hide BoxDecoration, BoxShadow; import 'package:flutter_inset_box_shadow/flutter_inset_box_shadow.dart'; // As both packages contains BoxDecoration and BoxShadow, so hiding them in from one of the package to avoid Diamond Problem
Después de las importaciones, crearemos sombras insertadas usando el código a continuación.
Dart
class NeumorphismPage extends StatefulWidget { const NeumorphismPage({Key? key}) : super(key: key); @override State<NeumorphismPage> createState() => _NeumorphismPageState(); } class _NeumorphismPageState extends State<NeumorphismPage> { bool _isElevated = false; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[300], body: Center( child: GestureDetector( onTap: () { setState(() { _isElevated = !_isElevated; }); }, child: AnimatedContainer( child: Icon( Icons.power_settings_new, size: 80, // Changing icon color on // the basis of it's elevation color: _isElevated ? Colors.grey : Color.fromARGB(255, 83, 220, 230), ), // Providing duration parameter // to create animation duration: const Duration( milliseconds: 200, ), height: 200, width: 200, decoration: BoxDecoration( color: Colors.grey[300], shape: BoxShape.circle, // when _isElevated is false, value // of inset parameter will be true // that will create depth effect. boxShadow: _isElevated ? // Elevated Effect [ const BoxShadow( color: Color(0xFFBEBEBE), // Shadow for bottom right corner offset: Offset(10, 10), blurRadius: 30, spreadRadius: 1, inset: false, ), const BoxShadow( color: Colors.white, // Shadow for top left corner offset: Offset(-10, -10), blurRadius: 30, spreadRadius: 1, inset: false, ), ] : // Depth Effect [ const BoxShadow( color: Color(0xFFBEBEBE), // Shadow for bottom right corner offset: Offset(10, 10), blurRadius: 30, spreadRadius: 1, inset: true, ), const BoxShadow( color: Colors.white, // Shadow for top left corner offset: Offset(-10, -10), blurRadius: 30, spreadRadius: 1, inset: true, ), ], ), ), ), ), ); } }
Producción: